Qt 从 GUI 线程停止工作线程循环
Qt Stop worker thread loop from GUI Thread
我有一个工作线程,我试图通过一个按钮停止它。我有时会收到以下错误:
Fatal: QThread: Destroyed while thread is still running
这是我的代码。通过按下断开按钮,会发出一个信号以停止线程的 while 循环。
if (ui->connectButton->text() == "Connect") {
mUDPThread = new QThread;
mUDPWorker = new UDPThread(ui->HostTextEdit->toPlainText(), ui->portTextEdit->toPlainText().toInt());
mUDPWorker->moveToThread(mUDPThread);
connect(mUDPThread, SIGNAL(started()), mUDPWorker, SLOT(process()));
connect(mUDPWorker, SIGNAL(finished()), mUDPThread, SLOT(quit()));
connect(mUDPWorker, SIGNAL(finished()), mUDPWorker, SLOT(deleteLater()));
connect(mUDPWorker, SIGNAL(finished()), mUDPThread, SLOT(deleteLater()));
connect(this, SIGNAL(onExitThread()), mUDPWorker, SLOT(onExitThread()));
connect(this, SIGNAL(onDataIncome(QString)), mUDPWorker, SLOT(onDataIncome(QString)));
mUDPThread->start();
ui->connectButton->setText("Disconnect");
} else if (ui->connectButton->text() == "Disconnect") {
emit onExitThread();
ui->connectButton->setText("Connect");
}
工作线程:
void UDPThread::process() {
while (isRunning) {
QCoreApplication::processEvents();
...
}
emit finished();
}
void UDPThread::onExitThread() {
qDebug() << "onExitThread" << isRunning;
isRunning = false;
}
while (isRunning)
您正在那里阻塞线程,它的事件循环无法旋转以接收信号,它只能向具有旋转事件循环的其他线程发送信号。
您需要让您的工作人员非阻塞,将工作分成周期,在事件循环开始旋转和接收信号之间。在伪代码中:
if (isRunning) {
doWorkCycle();
scheduleNextWorkCycle();
} else emit finished();
有一个例子你可以看看。
解决了。错误在连接命令中:
connect(mUDPWorker, SIGNAL(finished()), mUDPThread, SLOT(deleteLater()));
至
connect(mUDPThread, SIGNAL(finished()), mUDPThread, SLOT(deleteLater()));
结果:
connect(mUDPThread, SIGNAL(started()), mUDPWorker, SLOT(process()));
connect(mUDPWorker, SIGNAL(finished()), mUDPThread, SLOT(quit()));
connect(mUDPWorker, SIGNAL(finished()), mUDPWorker, SLOT(deleteLater()));
connect(mUDPThread, SIGNAL(finished()), mUDPThread, SLOT(deleteLater()));
connect(this, SIGNAL(onExitThread()), mUDPWorker, SLOT(onExitThread()));
connect(this, SIGNAL(onDataIncome(QString)), mUDPWorker, SLOT(onDataIncome(QString)));
我有一个工作线程,我试图通过一个按钮停止它。我有时会收到以下错误:
Fatal: QThread: Destroyed while thread is still running
这是我的代码。通过按下断开按钮,会发出一个信号以停止线程的 while 循环。
if (ui->connectButton->text() == "Connect") {
mUDPThread = new QThread;
mUDPWorker = new UDPThread(ui->HostTextEdit->toPlainText(), ui->portTextEdit->toPlainText().toInt());
mUDPWorker->moveToThread(mUDPThread);
connect(mUDPThread, SIGNAL(started()), mUDPWorker, SLOT(process()));
connect(mUDPWorker, SIGNAL(finished()), mUDPThread, SLOT(quit()));
connect(mUDPWorker, SIGNAL(finished()), mUDPWorker, SLOT(deleteLater()));
connect(mUDPWorker, SIGNAL(finished()), mUDPThread, SLOT(deleteLater()));
connect(this, SIGNAL(onExitThread()), mUDPWorker, SLOT(onExitThread()));
connect(this, SIGNAL(onDataIncome(QString)), mUDPWorker, SLOT(onDataIncome(QString)));
mUDPThread->start();
ui->connectButton->setText("Disconnect");
} else if (ui->connectButton->text() == "Disconnect") {
emit onExitThread();
ui->connectButton->setText("Connect");
}
工作线程:
void UDPThread::process() {
while (isRunning) {
QCoreApplication::processEvents();
...
}
emit finished();
}
void UDPThread::onExitThread() {
qDebug() << "onExitThread" << isRunning;
isRunning = false;
}
while (isRunning)
您正在那里阻塞线程,它的事件循环无法旋转以接收信号,它只能向具有旋转事件循环的其他线程发送信号。
您需要让您的工作人员非阻塞,将工作分成周期,在事件循环开始旋转和接收信号之间。在伪代码中:
if (isRunning) {
doWorkCycle();
scheduleNextWorkCycle();
} else emit finished();
有一个例子你可以看看
解决了。错误在连接命令中:
connect(mUDPWorker, SIGNAL(finished()), mUDPThread, SLOT(deleteLater()));
至
connect(mUDPThread, SIGNAL(finished()), mUDPThread, SLOT(deleteLater()));
结果:
connect(mUDPThread, SIGNAL(started()), mUDPWorker, SLOT(process()));
connect(mUDPWorker, SIGNAL(finished()), mUDPThread, SLOT(quit()));
connect(mUDPWorker, SIGNAL(finished()), mUDPWorker, SLOT(deleteLater()));
connect(mUDPThread, SIGNAL(finished()), mUDPThread, SLOT(deleteLater()));
connect(this, SIGNAL(onExitThread()), mUDPWorker, SLOT(onExitThread()));
connect(this, SIGNAL(onDataIncome(QString)), mUDPWorker, SLOT(onDataIncome(QString)));