可以在 QObject::connect() C++中连接 QML 对象现有信号?

It is possible connect a QML Object existing signal in C++ QObject::connect()?

本文关键字:对象 QML 连接 信号 C++ QObject connect      更新时间:2023-10-16

QML TreeView 有一个信号,名为:doubleClicked(QModelIndex(

参考: https://doc.qt.io/qt-5.10/qml-qtquick-controls-treeview.html#doubleClicked-signal

它可以在C++ QObject::connect(( 中连接现有信号?

我试过这个:

QQmlApplicationEngine engine;
QObject *myTreeMenu = engine.rootObjects().at(0)->findChild<QObject*>("myTreeMenu");
connect(myTreeMenu , SIGNAL(doubleClicked(QModelIndex)), this, SLOT(slotModelClicked(QModelIndex)));

但是我收到此返回错误:

QObject::connect: No such signal TreeView_QMLTYPE_63_QML_68::doubleClicked(QModelIndex) in '...'
QObject::connect:  (sender name:   'myTreeMenu ')

Qt 5.11的文档解释了为什么这不是使用C++和QML的最佳方式。我建议您改为在C++对象中公开一个插槽或Q_INVOKABLE,并在onDoubleClicked处理程序中调用它:

Q_INVOKABLE void doStuff();

在 QML 中:

onDoubleClicked: cppObject.doStuff()

该文档有一个"之前和之后"示例来演示这一点;这是其中的大部分内容:

使用这种方法,对对象的引用是从 QML 中"拉取"的。这 问题是C++逻辑层依赖于QML 表示层。如果我们要以这样的方式重构 QML: 对象名称更改,或者某些其他更改破坏了 找到QML对象C++,我们的工作流程变得更加多 复杂而乏味。

重构QML比重构C++要容易得多,所以为了 使维护无痛,我们应该努力让C++类型不知情 尽可能多地使用QML。这可以通过"推动"来实现 对 QML 中C++类型的引用:

int main(int argc, char *argv[])
{
QGuiApplication app(argc, argv);
Backend backend;
QQmlApplicationEngine engine;
engine.rootContext()->setContextProperty("backend", &backend);
engine.load(QUrl(QStringLiteral("qrc:/main.qml")));
if (engine.rootObjects().isEmpty())
return -1;
return app.exec();
}

然后,QML 直接调用C++槽:

import QtQuick 2.11
import QtQuick.Controls 2.4
Page {
Button {
text: qsTr("Restore default settings")
onClicked: backend.restoreDefaults()
}
}

使用这种方法,C++如果 QML将来需要重构。

在上面的示例中,我们将根上下文上的上下文属性设置为 向 QML 公开C++对象。这意味着该属性是 可用于发动机加载的每个组件。上下文属性 对于必须在 QML 可用后立即可用的对象很有用 已加载,无法在 QML 中实例化。

集成QML和C++展示了一种替代方法,其中QML是QML的 知道C++类型,以便它可以自行实例化它。