Solved QThread with loop cannot have other slot called (while loop is running) ?
-
Hello,
I have a simple question :
I have a QThread with a compute function called when the thread is started :void MyThread::compute() { while(m_run) {
//do things QThread::sleep(1000); } emit(finished());
}
Now that will run until I ask the thread to stop.
Other than that I have another slot that should be called more than once while this is running :void MyThread::deleteThing(const QString& name) { qDebug() << QString("delete"); QMutexLocker locker(&m_mutex); //things to delete }
My issue is that this slot is never called while the main loop is running.
What should I do differently ? I shouldn't use thread here ?rXp
-
Hi
Signals and slots need a event loop running. (exec())
so if u also overrode run() and call compute it might be therefore. Default it does call exec()
Maybe using a worker object will just work for you.https://mayaposch.wordpress.com/2011/11/01/how-to-really-truly-use-qthreads-the-full-explanation/
also look here
https://bugreports.qt.io/secure/attachment/64230/qsp-no-freeze-workaround-windows.zip
for other sample. -
@mrjj I did it this way :
mythread= new QThread; MyWorker* worker = new MyWorker(); worker->moveToThread(mythread); connect(worker, SIGNAL(threadFinished(const QString&)), this, SLOT(updateStatus(const QString&))); connect(mythread, SIGNAL(started()), worker, SLOT(compute())); connect(worker, SIGNAL(finished()), mythread, SLOT(quit())); connect(worker, SIGNAL(finished()), worker, SLOT(deleteLater())); connect(mythread, SIGNAL(finished()), worker, SLOT(stop())); connect(this, SIGNAL(deleteThing(const QString&)), worker, SLOT(deleteThing(const QString&))); mythread->start();
So my worker is put into a thread and the slot and signal a connected to my main UI class.
-
@rXpSwiss
Super.
So that works now? -
@mrjj No, that was my solution from the beginning. :(
-
@rXpSwiss
ok but you show
void MyThread::compute()seems like a thread sub class, but its not ?
Its the worker ? -
@mrjj It is the worker.
The idea is that when I do myThread->start() the thread will call compute() in my worker so the main loop is started.
But while this loop runs, I can call no other signal in my worker. -
@rXpSwiss The compute() method is blocking the event loop, so as long as it runs no slots will be executed. You should at least call http://doc.qt.io/qt-5/qcoreapplication.html#processEvents in your loop, or redesign your thread to get rid of this blocking loop.
-
@jsulm
So as I thought my way of doing it is the problem.
Now this is my basic problem :
I have a list of things I need to check on every X seconds.
If a change is detected I will tell the main thread to update the UI.
If not keep checking.
On the other side you can add new things (that have their own thread (but not QT)) and I need to tell my worker that a new thing is here.So I should processEvents here ? Or how would you handle that ?
-
@rXpSwiss You should use QTimer set to 1 second timeout, connect a slot to it and in this slot check for changes. No need to have an endless loop for that. If this checking does not take long you can even do it in your GUI thread (so no need for a second thread).
-
@jsulm
Since the number of elements has no real limit in the code, I worry it still might block the GUI a bit.
But I could use QTimer in the thread.Edit : Thank you it works fine, I am still not used to all QT tools :)