[英]QT QThread::isrunning freeze program on Pi
我正在PI上測試程序,在主機PC上運行時不會顯示錯誤,而是在pi(CM3)上運行會凍結。
我正在嘗試使用多線程。
從主線程中,在構造函數中啟動QThread,然后當我單擊按鈕以打開新表單時,GUI凍結。 在按鈕插槽中,我需要在打開新表單之前檢查是否在構造函數中啟動了serial_works線程是否已完成,因此我添加了QThread :: isRunning()檢查;
Main_Form::Main_Form(QWidget *parent) :
QMainWindow(parent),
ui(new Ui::Main_Form)
{
ui->setupUi(this);
this->move(0,0);
this->setWindowFlags(Qt::Window | Qt::FramelessWindowHint);
connect(ui->btn,SIGNAL(clicked(bool)),this,SLOT(open_form()));
*serial_works = new SerialWorks();
serial_works->start();
}
void Main_form::open_form(){
std::cout<<"open form slot"<<std::endl;
int i = 0;
while(serial_works->isRunning()){
std::cout<<"WHILE"<<std::endl;
QThread::msleep(100);
i++;
if(i > 10){
serial_works->terminate();
}
Next_form *frm = new Next_form();
this.close();
frm->show();
}
Serial_works類中的run方法是
void Serial_works::run() {
my_function();
this->terminate();
this->wait();
}
void Serial_works::my_function(){
....stuff on serial
std::cout<<"serial works finished"<<std::endl;
}
在輸出上我得到
//serial works finished
//open_slot_form
控制台上沒有打印出“ WHILE”字樣,因此程序在檢查時卡住了
serial_works->isRunning()
問題出在哪兒? 在主機PC上,新窗體將按預期方式打開。
您試圖使用QThread而不了解該對象在做什么。 您想要做的是異步執行 : 做一些工作,完成后告訴我 。
編輯:發生了什么 :
open_form
open_form
之前執行運行 在PI上
this->terminate()
,現在正式死亡。 終止是停止QThread的一種殘酷方式。 我什至無法推測是否調用了wait()。 錯誤1:
Main_form::open_form()
在gui線程中執行,並且您正在等待事件。 這總是不正確的。 您的GUI會在您睡覺的時間內凍結。 使用信號和插槽或事件。
錯誤2:
Serial_works可能是Qthread的子類。 您將執行線程與管理該線程的對象混淆了。 您不應該繼承QThread 。
this->terminate();
this->wait();
工作線程正在執行該代碼。 你正在扼殺自己 ,那么等待你的死亡。 因此,根據實現的不同,您可能會永遠等待,崩潰等。
您需要做什么: 使用QFuture和QFutureWatcher 。
//inside Main_Form
QFutureWatcher<ReturnValueType> watcher;
void Main_form::open_form(){
// Instantiate the objects and connect to the finished signal.
connect(&this->watcher, SIGNAL(finished()), &this, SLOT(SignalWorkFinished()));
// Start the computation.
QFuture<ReturnValueType> future = QtConcurrent::run(stuffOnSerialFunction);
this->watcher.setFuture(future);
}
// now handle work finish
void SignalWorkFinished()
{
QFuture<ReturnValueType> future = watcher.future();
//do whatever you like
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.