I have a simple form UI that has a slot for a button, starting a thread:
void MainWindow::LoadImage()
{
aThread->run();
}
And the run() method looks like this:
void CameraThread::run()
{
qDebug("Staring Thread");
while(1)
{
qDebug("ping");
QThread::sleep(1);
}
}
When I click the button that calls LoadImage(), the UI becomes unresponsive. I periodically see the "ping" message as the debug output but the UI hangs, does not respond to anything. Why is my thread not running separately? CameraThread derived as public QThread I am using gcc version 4.4.3 (Ubuntu 4.4.3-4ubuntu5) with QT libraries and QT Creator from Ubuntu 10.04(x86) repositories.
QThread will notify you via a signal when the thread is started() and finished(), or you can use isFinished() and isRunning() to query the state of the thread. You can stop the thread by calling exit() or quit(). In extreme cases, you may want to forcibly terminate() an executing thread.
PyQt graphical user interface (GUI) applications have a main thread of execution that runs the event loop and GUI. If you launch a long-running task in this thread, then your GUI will freeze until the task terminates.
A QThread object manages one thread of control within the program. QThreads begin executing in run() . By default, run() starts the event loop by calling exec() and runs a Qt event loop inside the thread. You can use worker objects by moving them to the thread using moveToThread() .
To use it, prepare a QObject subclass with all your desired functionality in it. Then create a new QThread instance, push the QObject onto it using moveToThread(QThread*) of the QObject instance and call start() on the QThread instance. That's all.
Short answer: Start your thread by calling aThread->start();
not run()
, and make sure you thread's run() method is protected (not public).
Explanation
Calling start()
is the correct way to start the thread, as it provides priority scheduling and actually executes the run()
method in its own thread context.
It looks like you are going to be loading images in this thread, so I'm going to include some tips before you run into pitfalls many people fall into while using QThread
CameraThread
class will not necessarily run in the thread's context, remember only the run() method and methods called from it are running in a separate thread.IMHO, subclassing QThread in the majority of cases is not the way to go. You can do it much simpler with the following code, and it will save you many headaches.
class ImageLoader : public QObject {
Q_OBJECT
public slots:
void doWork()
{
// do work
}
};
void MainWindow::MainWindow(/*params*/)
{
ImageLoader loader;
QThread thread;
loader.moveToThread( &thread );
connect( this, SIGNAL( loadImage() ), &loader ,SLOT( doWork() ) );
thread.start();
// other initialization
}
void MainWindow::LoadImage()
{
emit loadImage();
}
Also read the Qt blog regarding this topic.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With