Можно ли подключить объект QML к существующему сигналу в C ++ QObject :: connect ()? - PullRequest
0 голосов
/ 07 мая 2018

QML TreeView имеет сигнал с именем: doubleClicked (QModelIndex)

ref: 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 голосов
/ 07 мая 2018

Документация для Qt 5.11 объясняет, почему это не лучший способ работы с C ++ и QML. Я бы предложил вам вместо этого выставить слот или Q_INVOKABLE в вашем объекте C ++ и вызвать его в обработчике 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 должен быть реорганизован в будущем.

В приведенном выше примере мы установили свойство контекста в корневом контексте на выставить объект C ++ в QML. Это означает, что свойство доступно для каждого компонента, загруженного двигателем. Свойства контекста полезны для объектов, которые должны быть доступны, как только QML загружен и не может быть создан в QML.

Интеграция QML и C ++ демонстрирует альтернативный подход, где QML осведомлен о типе C ++, чтобы он сам мог создавать его экземпляр.

...