简体   繁体   English

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

[英]Qt5 App crashes on close (QWidget::show)

So I have been stuck at this problem for a while now. 因此,我已经在这个问题上停留了一段时间。 For some reason, my application always crashes on close and this is the error message I get: 由于某些原因,我的应用程序总是在关闭时崩溃,这是我收到的错误消息:

The inferior stopped because it triggered an exception. 下级停止,因为它触发了异常。

Stopped in thread 0 by: Exception at 0x50c15a08, code: 0xc0000005: read access violation at: 0x0, flags=0x0 (first chance) 通过以下方式在线程0中停止:在0x50c15a08处发生异常,代码:0xc0000005:在0x0处发生读取访问冲突,标志= 0x0(第一次机会)

The stack shows the following: 堆栈显示以下内容:

QWidget::show Line: 7030 QWidget :: show Line:7030

And this is what my main.cpp currently looks like: 这是我的main.cpp当前的样子:

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

I have no clue why the crash is occurring. 我不知道为什么发生崩溃。

A little background: This is a multi-threaded application (using both QThread and QtConcurrent). 一点背景知识:这是一个多线程应用程序(同时使用QThread和QtConcurrent)。 When the threads are NOT started, the application closes just fine. 当未启动线程时,应用程序将关闭。 Hence I added the following check to ensure that the thread is being terminated properly but this is not helping: 因此,我添加了以下检查,以确保线程正确终止,但这无济于事:

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

EDIT: How the new thread was created 编辑:如何创建新线程

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();

...and this is how I am handling the deletion of the thread after the download completes: ...这就是下载完成后我如何处理线程的删除:

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

You should either listen for terminated signal from the thread or wait for the thread to terminate. 您应该侦听来自线程的终止信号,或者等待线程终止。 Telling the thread to terminate doesn't block, so if you then immediately accept the close event you will get your exception. 告诉线程终止不会阻塞,因此,如果您随后立即接受close事件,则会得到异常。

This is described in more detail in the documentation for the terminate slot 有关终止插槽的文档中有更详细的描述

Proper QThread stop code is: 正确的QThread停止代码为:

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

Also you have used moveToThread(this); 您还使用过moveToThread(this);

You need to moveToThread back to parent thread first. 您需要先将ToToThread返回到父线程。

For example your code is: 例如,您的代码是:

moveToThread(this);
start();

You need to save currentThread() before moveToThread() like this: 您需要像这样在moveToThread()之前保存currentThread():

QThread *savedThread=currentThread();

moveToThread(this);
start();

And before quit or terminate you need to restore it: 在退出或终止之前,您需要恢复它:

moveToThread(savedThread);

quit();
wait();

You can put it on destructor of course. 您当然可以将其放在析构函数上。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM