Q_ENUMS 在 QML 中“未定义”?

Posted

技术标签:

【中文标题】Q_ENUMS 在 QML 中“未定义”?【英文标题】:Q_ENUMS are "undefined" in QML? 【发布时间】:2014-01-11 19:27:13 【问题描述】:

枚举不适合我。

我已经在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 但与那个 bug 不同的是,我的根组件是一个裸露的 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 快速应用程序并粘贴即可。 【参考方案1】:

你的问题不是枚举的暴露,而是你有一个领先的下划线。一旦你删除它,它就会起作用。

您需要以大写字母开头的枚举值。需要一些规则来区分枚举与附加属性和枚举。前导大写表示枚举,其余表示附加属性(如果未设置,则为未定义)。

诚然,Qt 本身也有一个警告,因为如果您尝试将该枚举值分配给一个 int 或 var 属性,您目前没有收到警告,并且已经与当前维护者讨论了这个问题,这似乎是一个错误,稍后将修复。

请参阅下面的工作代码以及相应建议的解决方案:

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

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

【讨论】:

嘿伙计!!我犯了同样的错误。像魅力一样工作!一百万谢谢你的回答。我希望我可以放弃不止一个。 XOXO 这里也一样!谢谢您的帮助! :-)

以上是关于Q_ENUMS 在 QML 中“未定义”?的主要内容,如果未能解决你的问题,请参考以下文章

Qml - ReferenceError:屏幕未定义

QML 参考错误 - 在 c++/QML 集成期间未定义 <thing>

[Qt Quick 踩坑] QML端函数参数未定义

来自 Qt 的 QML 未定义变量

PyQt5 + QML:带有“无法将[未定义]分配给QString”的空窗口

我需要整合我的 c++ 代码和 qml。但是我在使用 qmlRegisterType 时遇到了许多错误“未定义对‘Middlemen::staticMetaObject’的引用”