Q_ENUMS在QML中为“未定义”?

6
枚举对我来说行不通。
  • 我已经使用Q_ENUMS()进行了注册
  • 我没有忘记Q_OBJECT宏定义
  • 类型是使用qmlRegisterType()进行注册的
  • 模块已在QML中导入
简而言之,一切都是“按照书本”操作的,但是由于某些原因,我继续在QML中得到每个枚举值的undefined。 我错过了什么吗?
class UI : public QQuickItem {
    Q_OBJECT
    Q_ENUMS(ObjectType)
public:
enum ObjectType {
        _Root = 0,
        _Block
    };
...
};

...

qmlRegisterType<UI>("Nodes", 1, 0, "UI");

...

import Nodes 1.0
...
console.log(UI._Root) // undefined

注意,已注册的枚举值确实可以用于元系统,但由于某种原因,它们在QML中无法使用。
更新:我刚刚发现了这个错误:https://bugreports.qt.io/browse/QTBUG-33248 但与那个错误不同的是,我的根组件是一个裸的UI,而不是一个以UI为根的自定义元素。
事实证明,在console.log()中使用QML中的枚举值是可行的,以下代码实际上可以工作。
class A : public QObject {
    Q_OBJECT
    Q_ENUMS(EA)
public:
    enum EA {
        EA_NULL = 0,
        EA_ONE
    };
};

class B : public A {
    Q_OBJECT
    Q_ENUMS(EB)
public:
    enum EB {
        EA_TWO = 2,
        EA_THREE
    };
};

#include "main.moc"

int main(int argc, char *argv[])
{
    QGuiApplication app(argc, argv);
    qmlRegisterType<A>("test", 1, 0, "A");
    qmlRegisterType<B>("test", 1, 0, "B");

    QtQuick2ApplicationViewer viewer;
    viewer.setMainQmlFile(QStringLiteral("qml/enums/main.qml"));
    viewer.showExpanded();

    return app.exec();
}

并且...

Component.onCompleted: {
        console.log(A.EA_NULL)
        console.log(A.EA_ONE)

        console.log(B.EA_NULL)
        console.log(B.EA_ONE)
        console.log(B.EA_TWO)
        console.log(B.EA_THREE)
    }

输出结果为:

0
1
0
1
2
3

所以,除了“你没有正确使用它”之外,我猜还有其他问题……这可能与我上面提到的错误有关,以及当我实例化UI元素时,实际上是实例化了一个QML组件,该组件是一个对象树,以UI作为根。虽然这在使用来自C++的指针与完整的QML对象时不会产生任何问题,但出现了某些原因导致枚举混乱。


我发布的那段代码应该可以编译。只需创建一个新的Qt Quick应用程序并粘贴即可。 - user2341104
2个回答

13

你的问题不在于枚举类型的暴露,而在于你有一个前导下划线。一旦去掉它,就可以正常工作。

你需要以大写字母开头来定义枚举值。这样做的原因是为了区分枚举类型和附加属性。以大写字母开头指的是枚举类型,其余部分指的是附加属性(如果未设置则为未定义)。

诚然,在Qt中也有一个警告,因为如果你尝试将该枚举值分配给int或var属性,目前不会收到警告。已经与现任维护者讨论过这个问题,似乎这是一个Bug,将在以后修复。

请参见下面的工作代码及相应的解决方案:

main.cpp

#include <QQuickView>
#include <QQuickItem>

#include <QGuiApplication>

#include <QUrl>

class UI : public QQuickItem {
    Q_OBJECT
    Q_ENUMS(ObjectType)
public:
enum ObjectType {
        Root = 0,
        _Block
    };
};

#include "main.moc"

int main(int argc, char **argv)
{
    QGuiApplication guiApplication(argc, argv);
    qmlRegisterType<UI>("Nodes", 1, 0, "UI");
    QQuickView *view = new QQuickView;
    view->setSource(QUrl::fromLocalFile("main.qml"));
    view->show();
    return guiApplication.exec();
}

main.qml

import Nodes 1.0
import QtQuick 2.0

Rectangle {
    id: button
    width: 500; height: 500

    MouseArea {
        anchors.fill: parent
        onClicked: console.log(UI.Root)
    }
}

main.pro

TEMPLATE = app
TARGET = main
QT += quick
SOURCES += main.cpp

构建和运行

qmake && make && ./main

输出

0

2

我遇到了完全相同的问题,感谢这些解决方案,我找到了问题所在。然而,如果其他人也遇到了相同的混乱,这里有一点更加清晰。

我正在像这样在QML中使用来自C ++的类,因此我在main.cpp中有类似于这样的东西

qmlRegisterType<EnumClass>("Enums", 1, 0, "EnumClass");

并且在.qml

import Enums 1.0

EnumClass {
    id: ec
}

我一直尝试访问ec.SomeEnum,但是一直得到undefined的结果,即使QtCreator自动补全提示ec.SomeEnum应该存在。

这根本行不通,要让它工作,我必须使用

EnumClass.SomeEnum

相反,就像他们在这里做的那样。


1
嘿,伙计!我也犯了同样的错误。这个方法太棒了!非常感谢你的答案。我希望我能给你更多的赞。爱你哦。 - zeFree
一样!感谢你的帮助! :-) - Alex

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接