QThread阻塞主应用程序

Ati*_*liz 9 c++ qt multithreading qthread

我有一个简单的表单UI,有一个按钮插槽,启动一个线程:

void MainWindow::LoadImage()
{
    aThread->run();
}
Run Code Online (Sandbox Code Playgroud)

run()方法如下所示:

void CameraThread::run()
{
    qDebug("Staring Thread");
    while(1)
    {
        qDebug("ping");
        QThread::sleep(1);
    }
}
Run Code Online (Sandbox Code Playgroud)

当我单击调用LoadImage()的按钮时,UI变得无法响应.我定期看到"ping"消息作为调试输出,但UI挂起,不响应任何事情.为什么我的线程没有单独运行?CameraThread派生为公共QThread我使用gcc版本4.4.3(Ubuntu 4.4.3-4ubuntu5)与QT库和QT Creator来自Ubuntu 10.04(x86)存储库.

Cas*_*sey 30

简短回答:通过调用aThread->start();not来启动你的线程run(),并确保线程的run()方法受到保护(不公开).

说明

调用start()启动线程的正确方法,因为它提供优先级调度并实际run()在其自己的线程上下文中执行该方法.

看起来你将要在这个帖子中加载图像,所以在你遇到许多人在使用QThread时遇到的陷阱之前我会提供一些提示

  1. QThread本身不是一个线程.它只是一个线程的包装,这带给我们..
  2. CameraThread类中定义的信号/槽不一定在线程的上下文中运行,请记住只有run()方法和从它调用的方法在一个单独的线程中运行.

恕我直言,在大多数情况下继承QThread 不是要走的路.使用以下代码可以更简单地完成它,它将为您节省许多麻烦.

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();
}
Run Code Online (Sandbox Code Playgroud)

另请阅读有关此主题的Qt博客.

  • 对,那是正确的.基本上,Qt文档具有误导性,因此导致许多人做了hacky事情(比如Qthread构造函数中的movetoThread(this)),这会导致问题.希望文档很快就会更新. (2认同)

Kam*_*mek 5

你必须调用thread-> start()不运行... run是线程的入口点.线程以start开始.你直接打电话,这就是你阻止gui的原因.检查QThread的文档.虚拟void QThread :: run()受到保护(并非没有原因)