首页 > 代码库 > QT Demo 之 window(3) Qt.quit()
QT Demo 之 window(3) Qt.quit()
在上一章《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的示例代码以及帮助文档做得还是不够太好,而这也不是第一次被坑了。
QT Demo 之 window(3) Qt.quit()