使用 QQmlContext::setContextObject 使 C++ 对象对 QML 可见

Using QQmlContext::setContextObject to make a C++ object visible to QML

本文关键字:QML 对象 可见 QQmlContext setContextObject 使用 C++      更新时间:2023-10-16

编辑:问题已解决。在下面查看我的编辑

我在使用 QQmlContext::setContextObject 使 C++ 对象对 QML 可见时遇到问题。我已经阅读了 QQmlContext 的文档链接,它建议我可以使用 setContextObject 使 QObject 派生类的Q_PROPERTY对 QML 可见。下面的代码说明了这个问题。

主.cpp

#include <QObject>
#include <QQmlEngine>
#include <QGuiApplication>
class MyClass : public QObject
{
   Q_OBJECT
   Q_PROPERTY(QString myProperty READ prop NOTIFY propChanged)
public:
   MyClass(QObject * parent = 0) : QObject(parent) {}
   QString prop() { return QString("Hello from MyClass"); }
Q_SIGNALS:
   void propChanged(void);
};
int main(int argc, char *argv[])
{
   QGuiApplication app(argc, argv);
   QQmlEngine engine;
   QQmlContext *objectContext = new QQmlContext(engine.rootContext());
   MyClass myClass;
   objectContext->setContextObject(&myClass);
   QQmlComponent component(&engine, "main.qml");
   QObject *object = component.create(objectContext);
   return app.exec();
}

主.qml

import QtQuick 2.1
import QtQuick.Controls 1.0
ApplicationWindow
{
   Text
   {
      text: myProperty
   }
}

当我运行这个程序时,我收到错误

file:///C:/Path/to/main.qml:8: ReferenceError: myProperty is not defined

提前感谢您的任何帮助。

环境。我在Windows 7上使用Qt 5.1.1,带有MSVC2010编译器


编辑。回答我自己的问题。干净的重建显示我的构建输出文件夹中显然包含一些过时的对象。

需要注意的一点是:MyClass 必须位于一个单独的文件中,否则 moc 编译器无法发挥其魔力。

我整理好的主.cpp现在看起来像这样

int main(int argc, char *argv[])
{
   QGuiApplication app(argc, argv);
   QQmlEngine engine;
   QQmlContext * context = new QQmlContext(engine.rootContext());
   QObject::connect(&engine, SIGNAL(quit()), QCoreApplication::instance(), SLOT(quit    ()));
   MyClass myClass;
   context->setContextObject(&myClass);
   QQmlComponent component(&engine, "main.qml");
   QQuickWindow * topLevel = qobject_cast<QQuickWindow*>(component.create(context));
   topLevel->show();
   int rc = app.exec();
   delete topLevel;
   delete context;
   return rc;
}

您可以尝试在 getter 函数降级中添加Q_INVOKABLE宏。如果它没有帮助,您可以考虑使用QQmlContext::setContextProperty来执行此操作。我从未见过有人使用 ::setContextObject 进行这种集成。