QThread阻塞主应用程序

时间:2010-07-09 14:47:45

标签: c++ qt multithreading qthread

我有一个简单的表单UI,它有一个按钮插槽,启动一个帖子:

void MainWindow::LoadImage()
{
    aThread->run();
}

run()方法如下所示:

void CameraThread::run()
{
    qDebug("Staring Thread");
    while(1)
    {
        qDebug("ping");
        QThread::sleep(1);
    }
}

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

3 个答案:

答案 0 :(得分:30)

简答:通过调用aThread->start();而不是run()来启动您的主题,并确保线程的run()方法受到保护(不公开)。

<强>解释

Calling start() is the correct way启动线程,因为它提供优先级调度并在其自己的线程上下文中实际执行run()方法。

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

  1. QThread本身不是一个线程。它只是一个线程的包装器,这将我们带到..
  2. CameraThread类中定义的信号/槽不一定在线程的上下文中运行,请记住只有run()方法和从它调用的方法在一个单独的线程中运行。
  3. 恕我直言,在多数案例中继承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();
    }
    

    另请阅读Qt blog有关此主题的内容。

答案 1 :(得分:5)

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

答案 2 :(得分:-1)

我认为问题可能是你没有在构造函数中调用QtCore.QThread._init __(self)。我遇到过同样的问题。另外我认为你不应该覆盖start函数,只需覆盖run()函数。这解决了我遇到的同样问题。即使没有任何sleep()延迟,窗口也应该响应。