Qt5应用程序在关闭时崩溃(QWidget :: show)

时间:2014-11-05 01:53:03

标签: c++ multithreading qt qt5

所以我一直坚持这个问题已经有一段时间了。出于某种原因,我的应用程序总是在关闭时崩溃,这是我收到的错误消息:

  

下级因为引发了异常而停止了。

     

在线程0中停止:0x50c15a08异常,代码:0xc0000005:读取访问冲突:0x0,flags = 0x0(第一次机会)

堆栈显示以下内容:

  

QWidget :: show Line:7030

这就是我的main.cpp目前的样子:

int main(int argc, char *argv[])
{    
    QApplication a(argc, argv);
    MainWindow w;
    w.show();
    return a.exec();
}

我不知道崩溃发生的原因。

一点背景:这是一个多线程应用程序(同时使用QThread和QtConcurrent)。当线程未启动时,应用程序关闭就好了。因此,我添加了以下检查以确保线程正确终止,但这没有帮助:

    void MainWindow::closeEvent(QCloseEvent *event)
    {
            if (thread->isRunning()) {
                thread->terminate();
                while(!thread->isFinished()){
                }
                event->accept();
            }
    }

编辑:新线程的创建方式

QThread *myThread = new QThread(this);
        Worker *worker  = new Worker(this, user, p);
        worker->moveToThread(myThread);

        connect(myThread, SIGNAL(started()), worker, SLOT(doWork()));
        connect(worker, SIGNAL(workDone()), this, SLOT(deleteThread()));
        myThread->start();

...这就是我在下载完成后处理删除线程的方式:

void MainWindow::deleteThread(){
    worker->deleteLater();
    myThread->quit();
    while(!myThread->isFinished()){
    }
    myThread->deleteLater();
}

2 个答案:

答案 0 :(得分:1)

您应该监听来自线程的终止信号或等待线程终止。告诉线程终止不会阻止,所以如果你立即接受close事件,你将获得异常。

terminate slot

的文档中对此进行了更详细的描述

答案 1 :(得分:1)

正确的QThread停止代码是:

myThread->quit();
myThread->wait();

你也使用了moveToThread(this);

您需要先将ToThread移回父线程。

例如,您的代码是:

moveToThread(this);
start();

你需要在moveToThread()之前保存currentThread(),如下所示:

QThread *savedThread=currentThread();

moveToThread(this);
start();

在退出或终止之前,您需要恢复它:

moveToThread(savedThread);

quit();
wait();

当然,你可以把它放在析构函数上。