我有一个简单的表单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。
答案 0 :(得分:30)
简答:通过调用aThread->start();
而不是run()
来启动您的主题,并确保线程的run()方法受到保护(不公开)。
<强>解释强>
Calling start()
is the correct way启动线程,因为它提供优先级调度并在其自己的线程上下文中实际执行run()
方法。
看起来你将要在这个帖子中加载图片,所以在你遇到很多人使用QThread时遇到的陷阱之前我会先提供一些提示
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();
}
另请阅读Qt blog有关此主题的内容。
答案 1 :(得分:5)
你必须调用thread-&gt; start()不运行... run是线程的入口点。线程以start开始。你直接打电话,这就是你阻止gui的原因。检查QThread的文档。虚拟void QThread :: run()受到保护(并非没有理由)
答案 2 :(得分:-1)
我认为问题可能是你没有在构造函数中调用QtCore.QThread._init __(self)。我遇到过同样的问题。另外我认为你不应该覆盖start函数,只需覆盖run()函数。这解决了我遇到的同样问题。即使没有任何sleep()延迟,窗口也应该响应。