c++ - 可以在 C++ QObject::connect() 中连接 QML 对象现有信号吗?
问题描述
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 的最佳方式。我建议您改为公开一个插槽或Q_INVOKABLE
在您的 C++ 对象中并在处理程序中调用它onDoubleClicked
:
Q_INVOKABLE void doStuff();
在 QML 中:
onDoubleClicked: cppObject.doStuff()
该文档有一个“之前和之后”示例来证明这一点;这是其中的大部分:
使用这种方法,对对象的引用是从 QML 中“拉出”的。问题在于 C++ 逻辑层依赖于 QML 表示层。如果我们以 objectName 更改的方式重构 QML,或者某些其他更改破坏了 C++ 查找 QML 对象的能力,我们的工作流程将变得更加复杂和乏味。
重构 QML 比重构 C++ 容易得多,所以为了让维护无痛,我们应该尽量让 C++ 类型不知道 QML。这可以通过将 C++ 类型的引用“推送”到 QML 中来实现:
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() } }
使用这种方法,如果将来需要重构 QML,C++ 将保持不变。
在上面的示例中,我们在根上下文上设置了一个上下文属性,以将 C++ 对象公开给 QML。这意味着该属性可用于引擎加载的每个组件。上下文属性对于加载 QML 后必须立即可用且无法在 QML 中实例化的对象很有用。
集成 QML 和 C++演示了另一种方法,其中 QML 可以识别 C++ 类型,以便它可以自己实例化它。
推荐阅读
- java - 在 Eclipse IDE 中导入并运行一个 maven 项目
- python - 确定 unicode 字符是否存在于 unicode 子集中
- c++ - 获取字符串大小的各种方法之间的比较
- python - plotly 4.1没有情节
- docker - Docker Image推送到谷歌容器注册表不起作用
- java - 请设置 JAVA_HOME 变量
- ios - 使用通用协议过滤子视图数组
- python - 错误:只能比较标记相同的 DataFrame 对象
- python - 如何修复 python 3.7 中的“RuntimeError: input(): lost sys.stdin”错误
- python - 使用布尔键值对将字符串转换为字典格式