Reputation: 315
I'm testing a programm on my PI.When running it on the host pc no error is shown, instead , running it on pi (CM3) it freezes.
I'm trying to use multithreading.
From the main thread, in the constructor an QThread is started, then when I click on the button to open a new form the GUI freezes. In the button slot I need to check if the serial_works thread has been started in the constructor has finished before opening a new form, so I added a QThread::isRunning() check;
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();
}
the run method in the Serial_works class is
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;
}
on the output i get
//serial works finished
//open_slot_form
no WHILE is printed out on the console,thus the program get stuck on the while check
serial_works->isRunning()
Where is the problem? On the the host pc, the new form opens as expected.
Upvotes: 0
Views: 504
Reputation: 22910
You are trying to use QThread without understanding what is this object doing. What you want to do is asynchronous execution : Do some work and when you are done let me know.
Edit : What is Happening :
open_form
before the worker executes runopen_form
On PI
this->terminate()
and is now officially dead. terminate is a brutal way of stopping a QThread..I cannot even speculate whether wait() is called.Error 1 :
Main_form::open_form()
is executing in the gui thread, and you are sleeping on a event. This is always incorrect. You GUI will freeze for the amout of time you are sleeping. Use signals and slots or events.
Error 2 :
Serial_works is likely a subclass of Qthread. You are confusing a thread of execution with the object managing that thread. You should not subclass QThread.
this->terminate();
this->wait();
The worker thread is executing that code. You are killing yourself then waiting on your death. So depending on the implementation you may wait forever , crash, etc....
What you need to do : 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
}
Upvotes: 1