如何在 C++ 端获取 QQuickItem 的有效实例

How to get a valid instance of a QQuickItem on C++ side

好的。我已经搜索了很多但还没有找到好的解决方案。我是 Qt 的新手。我有一个 class 是 QQuickItem 像这样,

class MyQuickItemClass : public QQuickItem
{
    Q_OBJECT
    SetInfo(SomeCppClass object)
};

我在我的 main.cpp 中做了一个 qmlRegisterType 以像这样在 qml 端注册它,

qmlRegisterType< MyQuickItemClass >("MyQuickItemClass", 1, 0, "MyQuickItemClass");

到这里为止一切都很好。但是 -> 我想在 MyQuickItemClass 中设置一个对象实例和一些属性,其中还有一些 C++ 逻辑,然后将 MyQuickItemClass 对象传递给 qml。或者,从 Qml 获取 MyQuickItemClass 的有效实例。 如何在 main.cpp 的 C++ 端从 QML 获取 vlid 实例 MyQuickItemClass 对象实例?

我尝试从 link 中学习以下知识。但是这种技术创建了两个单独的 MyQuickItemClass 对象。一个来自 QML,一个来自 c++ 侧。因此对我不起作用。

以下是我经过大量搜索后尝试执行此操作的方法。

int main(int argc, char *argv[]) 
{
  qmlRegisterType< MyQuickItemClass >("MyQuickItemClass", 1, 0, "MyQuickItemClass");
  QQmlApplicationEngine engine;
  SomeCppClass someCppClassObject;
  someCppClassObject.updateSomething();

  MyQuickItemClass myquickItemObject;
  myquickItemObject.SetInfo(someCppClassObject);
  engine.rootContext()->setContextProperty("myquickItemObject", &myquickItemObject);

  engine.load(QUrl(QStringLiteral("qrc:/qml/main.qml")));
  return app.exec();
}

但是,执行上述操作会使 MyQuickItemClass 的构造函数被调用两次。当我创建一个对象时,一次来自 cpp 侧,一次来自 qml 侧。通过在 MyQuickItemClass 的构造函数中也放置一个断点来验证这一点。结果,当程序运行时,我设置的 someCppClassObjectMyQuickItemClass 内部为空。因为qml最终调用了MyQuickItemClass来实例化,因此忽略了我在main.cpp.

中创建的MyQuickItemClass对象

这是我的 qml MyQuickItemClass 代码:

import QtQuick 2.5
import MyQuickItemClass 1.0

ParentContainerItem {
  id: parentItem
  color: "black"

  MyQuickItemClass {
      id: myQuickItemID
      visible: true
      objectName: "myQuickItem"

      property bool someProperty1: false
      property bool someProperty2: true

      anchors.top: parent.top
      anchors.horizontalCenter: parent.horizontalCenter
  }

  //Other qml components
}

这是C++class,其对象需要设置成MyQuickItemClass

SomeCppClass {
  //Pure C++ class. No Qt
}

请注意,我需要保留 MyQuickItemClass 来自 QQuickItem。请建议...

一般来说,避免访问 QML 实例化对象是个好主意 from outside,因为大多数访问方法都生成了从 C++ 到 QML 的依赖性,限制了 QML 树的完成方式。

例如要求某些对象在特定时间点存在,具有特定的 objectName 值等

最好通过在公开的 C++ object/API 上调用方法从 QML 端 "register" 对象,或者使 QML 实例化对象从其自己的 C++ 代码中注册自身。

后者显然本质上是自动的,即这样的 class 的每个实例都会这样做,而前者则由 QML 代码自行决定要让哪些创建的实例为人所知。

根据讨论中的建议执行以下操作 解决了问题并获得了 QuickItem qml 文件的有效对象

QQuickItem *myItem = engine.rootObjects()[0]->findChild<QQuickItem *>("myQuickItem");