QThread阻塞主应用程序 [英] QThread blocking main application

查看:262
本文介绍了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库和QT Creator从Ubuntu 10.04(x86)存储库。

通过调用 aThread-> start(); 启动你的线程。不要 run(),并确保线程的run()方法是protected(不公开)。



strong>说明



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



看起来你要在这个线程中加载图像,所以我要去包括一些提示,在你陷入陷阱许多人在使用QThread之前陷入


  1. QThread本身不是一个线程 CameraThread 中定义的 类不一定在线程的上下文中运行,记住只有run()方法和从它调用的方法在单独的线程中运行。

IMHO,在 的情况下将QThread子类化的方式。

$

 您可以使用以下代码简化操作, class ImageLoader:public QObject {
Q_OBJECT
public slots:
void doWork()
{
// do work
}
}

void MainWindow :: MainWindow(/ * params * /)
{
ImageLoader loader;
QThread线程;
loader.moveToThread(& thread);
connect(this,SIGNAL(loadImage()),& loader,SLOT(doWork()));
thread.start();
//其他初始化
}
void MainWindow :: LoadImage()
{
emit loadImage();
}

同时阅读 Qt blog 有关此主题。


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.

解决方案

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.

这篇关于QThread阻塞主应用程序的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆