将 QObject* 设置为 QMLEngine 根上下文属性

Posted

技术标签:

【中文标题】将 QObject* 设置为 QMLEngine 根上下文属性【英文标题】:Setting QObject* as QMLEngine root context property 【发布时间】:2018-03-01 17:33:59 【问题描述】:

在我当前基于 Qt-Quick-UI 的 C++ 应用程序中,我想为我的 UI 提供带有 Q_PROPERTY(QAbstractListModel * ...)QObject

class MyClass : public QObject

 Q_OBJECT
 Q_PROPERTY(MyListModel* model READ model CONSTANT)
 public:
  const MyListModel* model() const return m_model.get();
 private:
  std::unique_ptr<MyListModel> m_model;

基于documentation,我理解这应该起作用的方式是,例如我的 main.cpp 我执行以下操作:

int main(int argc, char *argv[])

 std::unique_ptr<QCoreApplication> app;  // allows both console and GUI mode
 BackendController controller;  // holds a MyClass object and according (pointer-typed) getter
 std::unique_ptr<QQmlApplicationEngine> qmlengine;  // needed for GUI mode
 if(GUI_MODE)
 
  app.reset(new QApplication(argc, argv));
  qmlengine.reset(new QQmlApplicationEngine(app));
  qmlengine->rootContext()->setContextProperty("myobject", controller.getMyObject());
  engine.load(QUrl(QStringLiteral("qrc:/uimain.qml")));
  auto rcontext = qmlengine->rootContext();
  // else ...
 return app->exec();

我希望能够在我的 QML 中做这样的事情:

ListView 
  id: listview
  model: myobject.model
  delegate: Text 
    text: "An entry"
  

但是,即使我确保MyListModel 中有条目,我的ListView 仍为空。这就是为什么我放入auto rcontext 行,在那里设置断点并运行调试器(在尝试了无数其他方法来检查为什么没有显示之后)的原因。

MyObject 存储在BackendController 类中的指针(以及getter 返回的指针)与rcontext 中设置的上下文属性进行比较时,出现了不匹配。调试器指出我设置的“myobject”属性是QVariant&lt;bool&gt;(评估为true),并且在提取实际存储的值(即应该是QObject*)时,它与我传递给的指针不同setContextProperty 函数。

我注意到即使从main() 范围传递指针(如app.get())也会出现相同的行为,但在传递QVariant“原语”(如QStrings)时,它们会毫无问题地注册。

如果这是相关的:在初始化 QQmlApplicationEngine 和加载实际的 QML 文件之前,我还为 QML 可能接触的所有对象类型注册了(不可创建的)QML 类型(即MyObject 和 @ 987654343@) 并在 QML 中导入了相应的伪模块 - 无济于事。

所以我现在想知道这里发生了什么。 Qt 5.10 在给定 QObject*-type 参数时如何评估 setContextProperty 函数是否存在一些缺陷?还是我在这里的设置中严重忽略了某些东西?

【问题讨论】:

第一步是将您设置为myobject (controller.getMyObject()) 的指针存储在本地QVariant 中,并确保isValid() 为其返回true。我不记得是否有必要,但您可能必须像这样构造变体:QVariant::fromValue(controller.getMyObject()) 【参考方案1】:

事实证明,我的错误是使 MyClass getter 函数 (controller.getMyObject()) 成为 const 函数。显然,setContextProperty() 函数需要一些 QVariant绝不是 const QObject*

【讨论】:

以上是关于将 QObject* 设置为 QMLEngine 根上下文属性的主要内容,如果未能解决你的问题,请参考以下文章

QObject 使用 setParent() 将 QList 设置为父级

QT QObject分析

是否可以在单独的线程中将 QObject 设置为 QML 上下文属性?

如何将 QObject 指针的属性公开给 QML

访问从另一个 QObject 类继承的 QObject 类

QML:获取 QObject 父级