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

时间:2018-05-07 17:23:51

标签: c++ qt qml signals-slots

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 ')

1 个答案:

答案 0 :(得分:5)

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

Q_INVOKABLE void doStuff();
在QML中

onDoubleClicked: cppObject.doStuff()

该文档有一个“之前和之后”的例子来证明这一点;这是其中的大部分内容:

  

通过这种方法,可以从QML“拉出”对象的引用。该   这个问题是C ++逻辑层依赖于QML   表示层。如果我们以这样的方式重构QML   objectName更改,或其他一些更改破坏了该功能   在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()
    }
}
     

使用这种方法,C ++保持不变   QML需要在未来进行重构。

     

在上面的示例中,我们在根上下文中设置了一个context属性   将C ++对象公开给QML。这意味着该财产是   可用于引擎加载的每个组件。上下文属性   对于QML一旦必须可用的对象非常有用   已加载且无法在QML中实例化。

     

Integrating QML and C++演示了QML的替代方法   知道C ++类型,以便它可以自己实例化它。