It is possible connect a QML Object existing signa

2019-03-02 03:54发布

The QML TreeView has an signal named: doubleClicked(QModelIndex)

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

Its possible connect that existing signal in a C++ QObject::connect() ??

I tried this:

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

But i receive this return error:

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

1条回答
Luminary・发光体
2楼-- · 2019-03-02 04:50

The documentation for Qt 5.11 explains why this is not the best way to work with C++ and QML. I would suggest you instead expose a slot or Q_INVOKABLE in your C++ object and call that in the onDoubleClicked handler:

Q_INVOKABLE void doStuff();

in QML:

onDoubleClicked: cppObject.doStuff()

The documentation has a "before and after" example demonstrating this; here's the bulk of it:

With this approach, references to objects are "pulled" from QML. The problem with this is that the C++ logic layer depends on the QML presentation layer. If we were to refactor the QML in such a way that the objectName changes, or some other change breaks the ability for the C++ to find the QML object, our workflow becomes much more complicated and tedious.

Refactoring QML is a lot easier than refactoring C++, so in order to make maintenance pain-free, we should strive to keep C++ types unaware of QML as much as possible. This can be achieved by "pushing" references to C++ types into 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();
}

The QML then calls the C++ slot directly:

import QtQuick 2.11
import QtQuick.Controls 2.4

Page {
    Button {
        text: qsTr("Restore default settings")
        onClicked: backend.restoreDefaults()
    }
}

With this approach, the C++ remains unchanged in the event that the QML needs to be refactored in the future.

In the example above, we set a context property on the root context to expose the C++ object to QML. This means that the property is available to every component loaded by the engine. Context properties are useful for objects that must be available as soon as the QML is loaded and cannot be instantiated in QML.

Integrating QML and C++ demonstrates an alternative approach where QML is made aware of a C++ type so that it can instantiate it itself.

查看更多
登录 后发表回答