破坏qml对象后的信号槽连接?

时间:2018-04-11 11:47:06

标签: c++ qt qml

在破坏qml对象后,从c ++对象到qml对象槽的信号连接会发生什么?

Item {

    function qmlFunction() {
        cppObject.cppObjectFunction() 
    }

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

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

在我使用disconnect()编写Component.onDestruction之前,程序显示错误消息:

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

1 个答案:

答案 0 :(得分:0)

简单的解决方案是:

直接从QML中修改cppObject,以确保在加载QML文件之前通过添加到main.cpp文件来正确清理这两个对象

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 */ }