Подключение сигнал-слот после разрушения объектов qml?

Что происходит с подключением сигналов от объектов C++ к слотам объектов qml после уничтожения объектов qml?

Item {

    function qmlFunction() {
        cppObject.cppObjectFunction() 
    }

    Component.onCompleted: {
        cppObject.someSignal.connect(qmlFunction);
    }

    Component.onDestruction: {
        cppObject.someSignal.disconnect(qmlFunction);
    }
}

До того, как я написал Component.onDestruction с помощью disconnect (), программа отображала сообщение об ошибке:

qrc:/qml/xxxxxxxx.qml:77: TypeError: Cannot call method 'cppObjectFunction' of undefined

Отключение сигналов и слотов не выполняется автоматически?


Объект cppObject "всегда" существует и передается в qml следующим образом:

main.cpp

QQmlApplicationEngine engine;
Model* model = new Model::instance(&engine);
engine.setObjectOwnership(model, QQmlEngine::CppOwnership);
engine.rootContext()->setContextProperty("cppObject", model);
engine.load(QUrl(QStringLiteral("qrc:/qml/main.qml")));

Элемент QML загружается Loader и может быть перезагружен несколько раз в течение программы. Естественно, ошибка возникает после перезагрузки элемента QML и cppObject запускает сигнал someSignal.


в Windows: Qt 5.6.2 <- ошибка журнала моей программы для консоли отладки

на linux: Qt 5.9.2 <- моя программа вылетает

main.qml

import QtQuick 2.3
import QtQuick.Controls 1.2
import QtQuick.Layouts 1.1
import QtQuick.Dialogs 1.2
import QtQuick.Controls.Styles 1.3
import QtQuick.Window 2.2

Файл с ошибкой

import QtQuick 2.3
import QtQuick.Layouts 1.1
import QtQuick.Controls 1.3

Пожалуйста, предоставьте дополнительный код. Из того, что я вижу здесь, этого не должно происходить.

Rinat Veliakhmedov 11.04.2018 14:10

Не нашел ответа - док. Как создается cppObject? Каков его срок службы по сравнению с вашим товаром?

ymoreau 11.04.2018 15:05

Может проблема с JS подключениями ... Проблема все еще возникает при использовании QML-style Connections?

derM 11.04.2018 15:57

Если вы предоставите полный минимальный, полный и поддающийся проверке пример, мы можем увидеть, есть ли ошибка с вашей стороны или его следует опубликовать на bugreports.qt.io

derM 11.04.2018 16:13

Добавлена ​​информация о жизненном цикле объекта cpp. Если будет время, постараюсь сделать минимальный проект.

pier_nasos 11.04.2018 17:40

Какая у вас версия Qt?

talamaki 11.04.2018 20:47

добавлена ​​информация о версии qt

pier_nasos 12.04.2018 09:47

@pier_nasos С кодом, который показывает, что я попытался воспроизвести его ошибку, и у меня нет никаких проблем, я сделал это в Linux с Qt 5.10.1, только заменил Model для класса, который наследуется от QObject.

eyllanesc 12.04.2018 09:57

@pier_nasos Если вы хотите, чтобы мы вам помогли, вы должны предоставить минимальный воспроизводимый пример, этот код по определению должен быть полным, то есть без пробелов, и ваш код должен быть исправлен везде. ошибка могла быть вызвана реализацией Model.

eyllanesc 12.04.2018 09:58

Что в строке 77 /qml/xxxxxxxx.qml ?? вот где ошибка ...

mike510a 19.04.2018 10:39
2
10
517
1

Ответы 1

Простое решение:

создать cppObject непосредственно из QML, чтобы убедиться, что оба объекта должным образом очищены, путем добавления в ваш файл main.cpp перед загрузкой файла QML

qmlRegisterType<Model>("com.your.app", 1, 0, "CppModel");

а затем в свой файл QML включите:

import com.your.app 1.0

....

CppModel {
     id: cppObject

     onSomeSignal:  { cppObject.cppObjectFunction(); }
}

Таким образом, лишние соединения и лишняя функция qmlFunction () станут ненужными.

и, возможно, это тоже:

Если cppObjectFunction() - это общедоступный слот из cppObject, который определен на стороне C++, вы можете попробовать добавить Q_INVOKABLE перед ним, чтобы добавить его в систему метаобъектов.

Q_INVOKABLE void cppObjectFunction()  {  /* your code */ } 

Другие вопросы по теме