QThread blocking main application

匆匆过客 提交于 2020-01-20 22:14:06

问题


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.


回答1:


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

  1. QThread itself is not a thread. It is just a wrapper around a thread, this brings us to..
  2. signals/slots defined in the 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.




回答2:


You have to call thread->start() not run... run is an entry point for thread. Thread is started with start. You call directly run, that's why you block your gui. Check documentation of QThread. virtual void QThread::run() is protected (not without a reason)




回答3:


I think the problem could be that you are not calling QtCore.QThread._init__(self) in the constructor. I had the same issue. Also I think you should not override the start function, just override the run() function. This solved the same issue that I was having. Even without any sleep() delays, the window should be responsive.



来源:https://stackoverflow.com/questions/3213738/qthread-blocking-main-application

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!