如何正确删除和终止QThread

时间:2014-07-22 22:17:34

标签: c++ qt qthread qobject

我有一个继承自MyClass

的子类QThread

我使用MainWindow实例(this)的父代创建它:

mMyClass = new MyClass("some_value", 1, 5L, this);

我对Qt如何处理对象删除的理解是,当父项被删除时,每个具有父项的QObject都会被删除。

如果我的计划完成,我会收到警告QThread: Destroyed while thread is still running

我该如何解决这个问题?我在MainWindow的解构函数中使用以下代码尝试了它。不幸的是它无法正常工作:

if (mMyClass != 0 && mMyClass->isRunning()) {
    mMyClass->deleteLater();
    mMyClass->quit();
    mMyClass->wait();
}

1 个答案:

答案 0 :(得分:16)

你还没有指定你使用的Qt版本,所以我假设5.3。

另外,我相信你的线程代码,你有一些形式的无限循环,如下所示:

while (1) {
    // do something here.
}

首先,最好是在创建线程后将线程deleteLater()槽连接到finished()信号:

mMyClass = new MyClass("some_value", 1, 5L, this);
connect(mMyClass, SIGNAL(finished()), mMyClass, SLOT(deleteLater()));

这将导致线程在线程完成其作业后尽快被其父级删除。

现在,为了完成这项工作,Qt 5.2引入了方法QThread::requestInterruption()QThread::isInterruptionRequested()。您可以使用这些方法告诉您的线程完成这样的代码:

在您的主要课程退出代码中:

if (mMyClass != 0 && mMyClass->isRunning() ) {
    mMyClass->requestInterruption();
    mMyClass->wait();
}

在您的主题代码中

while ( !this->isInterruptionRequested() ) {
    // do your job here!
}

当关闭主窗口的代码被调用时,它会“中断”线程(如果它是有效的并且正在运行)。线程将检查它是否已被中断并将退出,触发finished()信号,这将触发deleteLater()插槽,最后您的主窗口将在事件循环或类中删除该类清理。

查看Qt 5.3 docs了解详情。