我有多个通过 StackView 推送的 qml 文件。我如何将它们连接到 C++
I have multiple qml Files that get pushed via StackView. How do I connect them to C++
我的项目包含 6 个 qml 文件:main.qml 打开一个新的 ApplicationWindow 并声明工具栏。它还使用 initalItem homescreen.qml 初始化 StackView。在主屏幕上,我有不同的按钮可以通过 stack.push("URL") 打开不同的 qml 文件。除了 main.qml 所有文件都以 Item{} 开头。
我已经能够连接来自 main.qml 和 home.qml 的信号。但是我一直无法访问堆栈中更深的对象。我不知道我是否需要更改我的 .cpp 代码以访问其他对象,或者我是否应该更改 StackView 的初始化,以便在开始时加载和访问所有文件。
这是代码,分解为最基本的内容:
main.qml
ApplicationWindow {
Rectangle{
id: homeButton
objectName: "homeButton"
signal qmlSignal(string msg)
MouseArea {
onClicked: {stack.push({item:"qrc:/home.qml}); homeButton.qmlSignal("Hello")}
}
}
StackView{
initalItem: "qrc:/home.qml"
}
}
secondframe.qml // 主屏幕之后出现的随机 qml 文件
Item {
Rectangle{
id: test
objectName: "test"
signal qmlSignal(string msg)
MouseArea {
onClicked: {stack.push({item:"qrc:/thirdframe.qml}); test.qmlSignal("Hello")}
}
}
}
main.cpp
QApplication app (argc, argv);
QQmlEngine enigne;
QQmlComponent component(&engine, QUrl(QStringLiteral("qrl:/main.qml")));
QObject *object = componet.create();
QQmlComponent newcomponent(&engine, QUrl(QStringLiteral("qrl:/secondframe.qml")));
QObject *newobject = newcomponet.create();
MyClass myClass
QObject *home = object->findChild<QObject*>("homeButton"); // I'm able to connect to every Object in the main.qml or home.qml
QObject::connect(home,SIGNAL(qmlSignal(Qstring)), &myClass, SLOT(cppSlot(QString)));
QObject *test = newobject->findChild<QObject*>("test"); // Can't connect to the Objects in secondframe.qml
QObject::connect(test,SIGNAL(qmlSignal(Qstring)), &myClass, SLOT(cppSlot(QString)));
一种比进入 QML 树并提取可能存在或可能不存在的对象更好的方法是向 QML 提供基于 C++ 的 API。
创建一个基于 class 的 QObject,它具有 QML 需要能够作为槽或 Q_INVOKABLE
调用的方法
class MyAPI : public QObject
{
Q_OBJECT
public slots:
void cppSlot(const QString &text);
};
创建一个实例并将其公开给 QML
MyAPI myApi;
QQmlEngine engine;
engine.rootContext()->setContextProperty("_cppApi", &myApi);
在 QML 中使用,就好像“_cppApi”是一个对象 ID
MouseArea {
onClicked: {stack.push({item:"qrc:/thirdframe.qml}); _cppApi.cppSlot("Hello")}
}
将 qmls 压入堆栈后,将可以访问对象。所以当你发出一些信号时,当对象将在堆栈上时,解决方案可能如下所示:
MyClass myClass
QObject *home = object->findChild<QObject*>("homeButton"); // I'm able to connect to every Object in the main.qml or home.qml
QObject::connect(home,SIGNAL(qmlSignal(Qstring)), &myClass, SLOT(cppSlot(QString)));
connect( myClass, MyClass::emitWhenQMLIsAlreadyOnTheStack, this, [this](){
QObject *test = newobject->findChild<QObject*>("test"); // Now you should be able to connect
QObject::connect(test,SIGNAL(qmlSignal(Qstring)), &myClass, SLOT(cppSlot(QString));
});
我的项目包含 6 个 qml 文件:main.qml 打开一个新的 ApplicationWindow 并声明工具栏。它还使用 initalItem homescreen.qml 初始化 StackView。在主屏幕上,我有不同的按钮可以通过 stack.push("URL") 打开不同的 qml 文件。除了 main.qml 所有文件都以 Item{} 开头。 我已经能够连接来自 main.qml 和 home.qml 的信号。但是我一直无法访问堆栈中更深的对象。我不知道我是否需要更改我的 .cpp 代码以访问其他对象,或者我是否应该更改 StackView 的初始化,以便在开始时加载和访问所有文件。 这是代码,分解为最基本的内容:
main.qml
ApplicationWindow { Rectangle{ id: homeButton objectName: "homeButton" signal qmlSignal(string msg) MouseArea { onClicked: {stack.push({item:"qrc:/home.qml}); homeButton.qmlSignal("Hello")} } } StackView{ initalItem: "qrc:/home.qml" }
}
secondframe.qml // 主屏幕之后出现的随机 qml 文件
Item { Rectangle{ id: test objectName: "test" signal qmlSignal(string msg) MouseArea { onClicked: {stack.push({item:"qrc:/thirdframe.qml}); test.qmlSignal("Hello")} } } }
main.cpp
QApplication app (argc, argv); QQmlEngine enigne; QQmlComponent component(&engine, QUrl(QStringLiteral("qrl:/main.qml"))); QObject *object = componet.create(); QQmlComponent newcomponent(&engine, QUrl(QStringLiteral("qrl:/secondframe.qml"))); QObject *newobject = newcomponet.create(); MyClass myClass QObject *home = object->findChild<QObject*>("homeButton"); // I'm able to connect to every Object in the main.qml or home.qml QObject::connect(home,SIGNAL(qmlSignal(Qstring)), &myClass, SLOT(cppSlot(QString))); QObject *test = newobject->findChild<QObject*>("test"); // Can't connect to the Objects in secondframe.qml QObject::connect(test,SIGNAL(qmlSignal(Qstring)), &myClass, SLOT(cppSlot(QString)));
一种比进入 QML 树并提取可能存在或可能不存在的对象更好的方法是向 QML 提供基于 C++ 的 API。
创建一个基于 class 的 QObject,它具有 QML 需要能够作为槽或
调用的方法Q_INVOKABLE
class MyAPI : public QObject { Q_OBJECT public slots: void cppSlot(const QString &text); };
创建一个实例并将其公开给 QML
MyAPI myApi; QQmlEngine engine; engine.rootContext()->setContextProperty("_cppApi", &myApi);
在 QML 中使用,就好像“_cppApi”是一个对象 ID
MouseArea { onClicked: {stack.push({item:"qrc:/thirdframe.qml}); _cppApi.cppSlot("Hello")} }
将 qmls 压入堆栈后,将可以访问对象。所以当你发出一些信号时,当对象将在堆栈上时,解决方案可能如下所示:
MyClass myClass
QObject *home = object->findChild<QObject*>("homeButton"); // I'm able to connect to every Object in the main.qml or home.qml
QObject::connect(home,SIGNAL(qmlSignal(Qstring)), &myClass, SLOT(cppSlot(QString)));
connect( myClass, MyClass::emitWhenQMLIsAlreadyOnTheStack, this, [this](){
QObject *test = newobject->findChild<QObject*>("test"); // Now you should be able to connect
QObject::connect(test,SIGNAL(qmlSignal(Qstring)), &myClass, SLOT(cppSlot(QString));
});