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) 以及 Ubuntu 10.04(x86) 存储库中的 QT 库和 QT Creator。
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.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
简短回答:通过调用
aThread->start();
而不是run()
来启动线程,并确保线程是 run()方法受保护(非公开)。说明
调用
start()
是启动线程的正确方法,因为它提供优先级调度并实际上在其自己的线程上下文中执行run()
方法。看起来您将在此线程中加载图像,因此我将在您遇到许多人在使用 QThread 时陷入的陷阱之前提供一些提示
恕我直言,在大多数情况下子类化 QThread 并不是正确的选择。您可以使用以下代码更简单地完成此操作,并且它将为您省去很多麻烦。
另请阅读有关此主题的 Qt 博客 。
Short answer: Start your thread by calling
aThread->start();
notrun()
, 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 therun()
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
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.
Also read the Qt blog regarding this topic.
你必须调用 thread->start() 而不是 run...run 是线程的入口点。线程通过 start 启动。你直接调用 run,这就是你阻止你的 gui 的原因。检查 QThread 的文档。 virtual void QThread::run() 受到保护(不是没有原因的)
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)
我认为问题可能是您没有在构造函数中调用 QtCore.QThread._init__(self) 。我有同样的问题。另外我认为你不应该重写 start 函数,只需重写 run() 函数。这解决了我遇到的同样的问题。即使没有任何 sleep() 延迟,窗口也应该具有响应能力。
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.