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

上一篇: QThread Windows not responding

下一篇: How to resize the QMenuBar in PyQt4 for a 4K display