2017-10-26 44 views
1

ボタンを停止しようとするワーカースレッドがあります。私は次のエラーを受け取ることがあります:Qt GUIからワーカースレッドループを停止します。スレッド

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

答えて

0

解決しました。エラーは、接続コマンド内であった:

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

while (isRunning)

あなたは、そのイベントループが信号を受信するためにスピンすることができない、それだけで、他のスレッドにシグナルを送ることができ、すぐそこにスレッドをブロックしていますスピンイベントループを伴う。

ワーカーをノンブロッキングにするか、イベントループをスピンして信号を受信するかのサイクルで分割する必要があります。擬似コードの場合:

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

hereの例があります。

+0

申し訳ありませんが、私は(のprocessEventsを呼び出す)と(完成発する)もちろん。私は質問を更新しました – momosxp

+0

@momosxpスレッドがブロックされているので、処理に強制することができるイベントは何も受信されないので、それが役に立ったとは思いません。それがうまく動作しても、 'processEvents()'を手作業で呼び出さなければならないことは、デザインが悪いことを示しています。 – dtech

+0

ご協力いただきありがとうございます。私はinvokemethodを使ってリンクに従ってそれを実装しようとしました。同様に、processEventsを使用せずに動作しますが、同じエラーメッセージでクラッシュすることがあります。 – momosxp

関連する問題