如何在 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
的构造函数中也放置一个断点来验证这一点。结果,当程序运行时,我设置的 someCppClassObject
在 MyQuickItemClass
内部为空。因为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");
好的。我已经搜索了很多但还没有找到好的解决方案。我是 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
的构造函数中也放置一个断点来验证这一点。结果,当程序运行时,我设置的 someCppClassObject
在 MyQuickItemClass
内部为空。因为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 代码自行决定要让哪些创建的实例为人所知。
根据讨论中的建议执行以下操作
QQuickItem *myItem = engine.rootObjects()[0]->findChild<QQuickItem *>("myQuickItem");