QThread Windows没有响应
我在Windows上的PyQt中编写了一个GUI程序。 我的程序中有一些昂贵的操作。 在这些操作正在运行时,程序在程序栏中显示“Not Responding”。
我认为它必须是这个操作块来更新UI的主线程,所以我用QThread编写多线程代码来测试它,但它仍然没有意义。
我写了一个小程序来测试它,这个操作并没有在新线程中运行,这里是我的小测试代码:
from PyQt5.QtCore import QThread, QObject, QCoreApplication, qDebug, QTimer class Worker(QObject): def on_timeout(self): qDebug('Worker.on_timeout get called from: %s' % hex(int(QThread.currentThreadId()))) if __name__ == '__main__': import sys app = QCoreApplication(sys.argv) qDebug('From main thread: %s' % hex(int(QThread.currentThreadId()))) t = QThread() qDebug(t) worker = Worker() timer = QTimer() timer.timeout.connect(worker.on_timeout) timer.start(1000) timer.moveToThread(t) worker.moveToThread(t) t.start() app.exec_()
这是输出:
From main thread: 0x634 Worker.on_timeout get called from: 0x634
您的程序有几个错误,并且不会生成您显示的输出。
首先,不可能将线程对象传递给qDebug
- 参数必须是字符串。 如果你想打印对象,使用qDebug(repr(obj))
- 甚至更好,只需使用print(obj)
。
其次,你不能在创建它的线程之外启动一个定时器。 你的例子在主线程中建立信号连接,并在主线程中启动计时器。 所以worker.on_timeout
将在主线程中被调用。 但是,如果您在将其移至工作线程后连接并启动计时器,则会出现此错误:
QObject :: startTimer:定时器只能用于使用QThread启动的线程
我认为使用计时器是不必要的,并且会混淆你的示例,所以最好将它完全抛弃。 相反,您应该将工作线程的started
信号连接到工作对象的run
方法。 要模拟长时间运行的操作,可以使用QThread.sleep()
:
from PyQt5.QtCore import QThread, QObject, QCoreApplication
class Worker(QObject):
def run(self):
print('Worker called from: %#x' % int(QThread.currentThreadId()))
QThread.sleep(2)
print('Finished')
QCoreApplication.quit()
if __name__ == '__main__':
import sys
app = QCoreApplication(sys.argv)
print('From main thread: %#x' % int(QThread.currentThreadId()))
t = QThread()
worker = Worker()
worker.moveToThread(t)
t.started.connect(worker.run)
t.start()
app.exec_()
最后,请注意,在将工作对象移动到线程后,应始终进行信号连接。 这个答案解释了原因。
链接地址: http://www.djcxy.com/p/64497.html