Qt从GUI线程

时间:2017-10-26 13:43:36

标签: c++ qt qthread

我有一个工作线程,我尝试通过按钮停止。我有时会收到以下错误:

Fatal: QThread: Destroyed while thread is still running

这是我的代码。通过按下断开按钮,可以发出信号以停止线程的循环。

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;
}

2 个答案:

答案 0 :(得分:2)

while (isRunning)

你正在阻塞线程,它的事件循环不能旋转以接收信号,它只能通过旋转事件循环向其他线程发送信号。

你需要让你的工作者无阻塞,在周期中分离工作,在事件循环之间进行旋转和接收信号。在伪代码中:

if (isRunning) {
  doWorkCycle();
  scheduleNextWorkCycle();
} else emit finished();

有一个例子,您可以查看here

答案 1 :(得分:0)

解决了它。错误发生在connect命令中:

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