QT Demo 之 window(3) Qt.quit()

本文详细介绍了在QT Demo中遇到的Qt.quit()使用问题,通过分析帮助文档和示例代码,解释了如何正确连接QQmlEngine::quit()信号到QCoreApplication::quit()槽以实现C++应用程序的退出。同时,讨论了Qt.quit()函数在QML中的作用,以及在没有正确处理quit()信号时可能导致的错误。文章还推荐了相关的学习资源,总结了QObject::connect()的基础应用。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

在上一章《QT Demo 之 window(2) Splash》学习中留下一个TODO没有解决,就是在示例代码中有这样的一段:

        MouseArea {
            anchors.fill: parent
            onClicked: Qt.quit()
        }
其本意就是在显示Splash Screen的时候,如果点击Splash Screen图片就会退出整个程序,但实际结果就是报了一行错误:
Signal QQmlEngine::quit() emitted, but no receivers connected to handle it.
程序仍然好好的进行着。

我们使用上面的错误提示信息作为关键字进行搜索,通过bing搜索找到的只有一个有效页面Qt Error: Signal QDeclarativeEngine::quit() emitted, but no receivers connected to handle it,在该页面中提到了正确的使用quit()的语法是:

connect(sender, SIGNAL(signalName(args)), receiver, SLOT(slotName(args)));

看到这里我是感觉到头痛了,这个什么和什么呢?说的语焉不详的,完全不知道怎么解决当前这个Demo的问题。

从帮助文档入手

那么就从Qt的帮助文档开始,先了解一下quit()函数的官方说明:
quit()
This function causes the QQmlEngine::quit() signal to be emitted. Within the Prototyping with qmlscene, this causes the launcher application to exit; to quit a C++ application when this method is called, connect the QQmlEngine::quit() signal to the QCoreApplication::quit() slot.

帮助文档中提到,如果要退出一个C++的应用程序,需要connect the QQmlEngine::quit() signal to the QCoreApplication::quit() slot.

这个时候我们就知道在上面提到了connect()函数调用就有关联了。

Qt.quit()示例代码

我们再次使用Qt.quit()作为关键字在bing上搜索,找到一个Closing a Qt Quick application from QML页面。

在示例代码中我们看到调用Qt.quit()函数的地方也是在Qml的MouseArea控件中通过onClicked事件响应函数中完成的,但是和Window示例代码中不同的地方在main.cpp中:

int main(int argc, char *argv[])
{
    QApplication app(argc, argv);
 
    QDeclarativeView view;
    view.setSource(QUrl("./ui.qml"));
    view.setResizeMode(QDeclarativeView::SizeRootObjectToView);
 
    <span style="color:#FF0000;">QObject::connect((QObject*)view.engine(), SIGNAL(quit()), &app, SLOT(quit()));</span>
 
    view.setGeometry(100,100, 800, 480);
    view.show();
 
    return app.exec();
}
注意,上面的红色部分,这个应该就是问题的关键。

因此,仿照这个示例代码,我们在Window示例项目的main.cpp中添加了下述代码:

    QObject::connect(&engine, SIGNAL(quit()), &app, SLOT(quit()));

再次运行程序,在Splash Screen出现的时候,单击鼠标左键,奇迹出现了:程序按照预期退出了

再次回到刚才的Closing a Qt Quick application from QML页面中,我们看到由下述的一行解释:
The calling of the Qt.quit() function in QML code caused the emission of the QDeclarativeEngine::quit() signal, and because this signal was connected to the QApplication::quit() slot, the application was closed.

看到这里,我们才了解到,原来在Qml中调用Qt.quit()函数,只是触发了一个QDeclarativeEngine::quit()的信号,在原来的代码中,由于没有任何地方处理这个信号,就会报出no receivers connected to handle it的错误,而通过添加QObject::connect(&engine, SIGNAL(quit()), &app, SLOT(quit()));代码后,就是把QDeclarativeEngine::quit()信号和QApplication::quit()方法关联起来了,最终会导致程序完全退出。

看到这里吐槽一句,其实默认的QDeclarativeEngine::quit()的信号就应该和QApplication::quit()方法关联起来,作为一种default的处理方法,如果需要自定义处理退出模式的话再通过一些方法来完成,而不是留下这样的一个坑。

扩展阅读

在检索资料时也看到了一些好的博客,总结的很好,推荐给大家:

Qt学习经验之quit()、exit()、close():详细讲解了Qt中的quit()、exit()、close()函数区别,并给出了如何自定义退出时的UI处理方法。

Qt--help:博客的名字虽然是Qt--help,但是实际上讲解了QObject::connect()函数,不算深入,但是可以稍微了解一下

总结

这一章只是解决了上一章中留下的一个TODO,初步学习了一下QObject::connect()函数。

只是在解决这个TODO的过程中,感觉Qt的示例代码以及帮助文档做得还是不够太好,而这也不是第一次被坑了。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值