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

QML Reference Error - <thing> is not defined during a c++/QML integration

我正在尝试构建混合的 c++/QML 应用程序,但在尝试使这两个部分通信和交互时遇到了问题。 objective 是通过 setContextProperties 方法在 QML 中使用嵌入式 C++ 对象,使用 QQmlApplicationEngine。

我一直在看这个 post 因为问题非常相似,但不幸的是解决方案不适用于此处。我还是 Qt 的新手,所以也许解决方案很明显,但我想不出来。

所以我有 3 个文件,main.cppthing.hmain.qml

main.cpp:

#include "thing.h"

int main(int argc, char *argv[])
{
    QCoreApplication::setAttribute(Qt::AA_EnableHighDpiScaling);
    QGuiApplication app(argc, argv);

    QQmlApplicationEngine engine;
    engine.load(QUrl(QStringLiteral("qrc:/main.qml")));
    if (engine.rootObjects().isEmpty())
        return -1;

    Thing thing;
    engine.rootContext()->setContextProperty("thing", &thing);
    thing.setColor(Qt::green);

    return app.exec();
}

调用 thing.h:

class Thing : public QObject
{
    Q_OBJECT
    Q_PROPERTY(QColor color READ color WRITE setColor NOTIFY colorChanged)

public:
    Thing() : _color(Qt::black), _text("text") { }

    Q_INVOKABLE void clicked() { setColor(Qt::blue); }

    QColor color() const {return _color;}
    void setColor(const QColor &color) {
        _color = color;
        emit colorChanged();
    }
signals:
    void colorChanged();

private:
    QColor _color;
};

和main.qml:

Window {id: main
    width: 100; height: 100
    color: thing.color

    MouseArea {
        anchors.fill: parent
        onClicked: thing.clicked();
    }
}

当运行这段代码时,我得到'qrc:/main.qml:6: ReferenceError: thing is not defined',它指的是在main.qml中执行color: thing.color。我怎样才能让它工作?

您可以尝试在加载主要组件之前公开您的根上下文 属性 "thing"。它将确保您的 "thing" 属性 在创建组件实例并首次评估其绑定后可用。

#include "thing.h"

int main(int argc, char *argv[])
{
    QCoreApplication::setAttribute(Qt::AA_EnableHighDpiScaling);
    QGuiApplication app(argc, argv);

    Thing thing;

    QQmlApplicationEngine engine;
    engine.rootContext()->setContextProperty("thing", &thing);
    engine.load(QUrl(QStringLiteral("qrc:/main.qml")));
    if (engine.rootObjects().isEmpty())
        return -1;

    thing.setColor(Qt::green);

    return app.exec();
}