c++ - 销毁 qml 对象后的信号槽连接?

标签 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:

主要.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 <- 我的程序崩溃了

主.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

最佳答案

简单的解决方案是:

直接从 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()是C++端定义的来自cppObject的public slot,你可以尝试在前面加上Q_INVOKABLE为了将它添加到元对象系统。

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

关于c++ - 销毁 qml 对象后的信号槽连接?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/49774324/

相关文章:

c++ - Qt变量生命周期的误解

c++ - QFontMetrics 返回不准确的结果

c++ - fork在递归函数中的使用

c++ - 如何在C++(QT框架)中构建一个带有UTF字符的字符串

c++ - 在二维图像上绘制欧拉角旋转模型

qt - 如何在 QML 中为矩形创建滚动条

qml - 如何重新排序 QML GridLayout 中的项目?

c++ - 将数据提供给 ChartView (LineSeries) - QML

c++ - C++透明类包装器有什么用

c++ - Winsock 接收额外数据