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