如何完全/正确地退出一个Qt程序从主要形式



我正在编写一个Qt程序(使用Qt 5.4),基于QTimer从网络摄像头读取帧,而不是一个单独的线程(间隔设置为20毫秒,当然它需要比1/50秒更长的时间从网络摄像头读取帧并处理它,我估计帧率可能是20 fps。无论如何,计时器循环时运行的函数是一个槽,如下所示:

///////////////////////////////////////////////////////////////////////////////////////////////////
void frmMain::processFrameAndUpdateGUI() {
bool blnFrameReadSuccessfully = capWebcam.read(matOriginal);      // get next frame from the webcam
if (!blnFrameReadSuccessfully || matOriginal.empty()) {           // if we did not get a frame
    QMessageBox::information(this, "", "unable to read from webcam nn exiting programn");
    QApplication::quit();
}
// process frame here . . .

这个想法是,如果在程序开始时可以成功读取网络摄像头,但随后无法读取(网络摄像头停止工作,用户不小心断开网络摄像头等),程序应该显示一个消息框,然后完全关闭自己。

在上面的情况下,如果我在程序运行时拔掉网络摄像头进行测试,消息框会按预期出现,但在选择OK后,会出现一个调试错误屏幕。如果我选择"中止",表单仍然在那里,不会响应。在多次尝试关闭窗体后,Windows询问"该程序似乎没有响应,您是否要关闭?"这时我可以关闭窗体。显然,这并没有达到预期的效果。

经过各种各样的谷歌搜索,我发现建议修改如下:

///////////////////////////////////////////////////////////////////////////////////////////////////
void frmMain::closeEvent(QCloseEvent *) {
    QApplication::quit();
}
///////////////////////////////////////////////////////////////////////////////////////////////////
void frmMain::processFrameAndUpdateGUI() {
bool blnFrameReadSuccessfully = capWebcam.read(matOriginal);      // get next frame from the webcam
if (!blnFrameReadSuccessfully || matOriginal.empty()) {           // if we did not get a frame
    QMessageBox::information(this, "", "unable to read from webcam nn exiting programn");
    closeEvent(new QCloseEvent());
}
// process frame here . . .

当我第一次看到这段代码时,我很乐观,但是它给了我与上面相同的结果(程序挂起,窗体仍然打开)。我使用OpenCV 2.4.11进行图像处理,我的程序有4个文件:

  • frmmain.h (.h为主窗体,它是用Qt Creator制作的标准QMainWindow)
  • frmmain.cpp (.cpp为主表单,上面代码所在的位置)
  • main.cpp(我没有改变Qt Creator的制作方式)
  • frmmain。ui(通过Qt Creator添加少量常见小部件的典型表单)

是的,我意识到我可以在一个可以显示文本的小部件上显示错误消息,从函数返回,并让用户关闭程序,但我正在寻找一个更优雅的解决方案。谁能提供进一步的建议,如何完全关闭图形Qt程序?请建议。

有两件事可以解决你的问题:

  1. 在显示消息框之前,使用stop()方法停止计时器。
  2. QApplication::quit()之后;return退出函数;你的函数可能最后一次运行到结束并且访问了无效的对象。

供其他人参考,Rafael Monteiro的回答是正确的。以下是更新后的代码(经过验证可以正常工作):

///////////////////////////////////////////////////////////////////////////////////////////////////
void frmMain::closeEvent(QCloseEvent *) {
    if(qtimer->isActive()) qtimer->stop();      // had to stop timer here !!!!!!!!
    QApplication::quit();
}
///////////////////////////////////////////////////////////////////////////////////////////////////
void frmMain::processFrameAndUpdateGUI() {
    bool blnFrameReadSuccessfully = capWebcam.read(matOriginal);                    // get next frame from the webcam
    if (!blnFrameReadSuccessfully || matOriginal.empty()) {                            // if we did not get a frame
        QMessageBox::information(this, "", "unable to read from webcam nn exiting programn");
        closeEvent(new QCloseEvent());
        return;          // had to add return here !!!!!!!!!
    }
    // rest of function here . . .

我应该提到我必须添加返回和停止计时器。谢谢拉斐尔!

相关内容

  • 没有找到相关文章

最新更新