QT QThread::isrunning 冻结 Pi 上的程序
QT QThread::isrunning freeze program on Pi
我正在我的 PI.When 运行 主机上测试一个程序,没有显示任何错误,相反,运行在 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_worksclass中的运行方法是
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,因此程序卡在了while check
serial_works->isRunning()
问题出在哪里?在主机上,新表单按预期打开。
您在不了解此对象的作用的情况下尝试使用 QThread。你想做的是异步执行:做一些工作,完成后告诉我。
编辑:发生了什么:
- 客户端:主线程在工作线程执行运行
之前执行open_form
- Rasberry Pi:worker 在主线程执行
open_form
之前执行 运行
圆周率
- serial_works->start() 启动 worker,先执行,然后完成 my_function.
- 工作人员致电
this->terminate()
,现已正式死亡。 terminate is a brutal way of stopping a QThread.。我什至无法推测是否调用了 wait()。
- 主线程执行open_form,worker已经是非运行nable。所以循环没有被执行并且 Next_form 永远不会被显示。
错误 1:
Main_form::open_form()
正在 gui 线程中执行,而您正在休眠一个事件。这总是不正确的。您的 GUI 将在您睡觉的时间内冻结。使用信号槽或事件。
错误 2:
Serial_works 可能是 Qthread 的子类。您将执行线程与管理该线程的对象混淆了。 你不应该继承 QThread.
this->terminate();
this->wait();
工作线程正在执行该代码。你在杀死自己自己然后等死。因此,根据实施情况,您可能会永远等待、崩溃等......
您需要做什么:
Use QFuture and 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
}
我正在我的 PI.When 运行 主机上测试一个程序,没有显示任何错误,相反,运行在 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_worksclass中的运行方法是
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,因此程序卡在了while check
serial_works->isRunning()
问题出在哪里?在主机上,新表单按预期打开。
您在不了解此对象的作用的情况下尝试使用 QThread。你想做的是异步执行:做一些工作,完成后告诉我。
编辑:发生了什么:
- 客户端:主线程在工作线程执行运行 之前执行
- Rasberry Pi:worker 在主线程执行
open_form
之前执行 运行
open_form
圆周率
- serial_works->start() 启动 worker,先执行,然后完成 my_function.
- 工作人员致电
this->terminate()
,现已正式死亡。 terminate is a brutal way of stopping a QThread.。我什至无法推测是否调用了 wait()。 - 主线程执行open_form,worker已经是非运行nable。所以循环没有被执行并且 Next_form 永远不会被显示。
错误 1:
Main_form::open_form()
正在 gui 线程中执行,而您正在休眠一个事件。这总是不正确的。您的 GUI 将在您睡觉的时间内冻结。使用信号槽或事件。
错误 2:
Serial_works 可能是 Qthread 的子类。您将执行线程与管理该线程的对象混淆了。 你不应该继承 QThread.
this->terminate();
this->wait();
工作线程正在执行该代码。你在杀死自己自己然后等死。因此,根据实施情况,您可能会永远等待、崩溃等......
您需要做什么: Use QFuture and 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
}