QThread Windows not responding
I wrote a GUI program in PyQt on Windows. There's some expensive operations in my program. While these operations are running, the program shows "Not Responding" in the program bar.
I think it must be this operation block the main thread to update the UI, so I write multi-threading code by QThread to test it, it still not make sense.
I wrote a small program to test it, the operation did not run in new thread at all, here is my small test code:
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_()
Here is the output:
From main thread: 0x634 Worker.on_timeout get called from: 0x634
Your program has several errors and does not produce the output that you show.
Firstly, it is not possible to pass a thread object to qDebug
- the argument must be a string. If you want to print objects, use qDebug(repr(obj))
- or even better, just use print(obj)
.
Secondly, you cannot start a timer outside of the thread that created it. Your example makes the signal connection in the main thread, and starts the timer in the main thread as well. So worker.on_timeout
will be called in the main thread. But if you connect and start the timer after moving it to the worker thread, you will get this error:
QObject::startTimer: Timers can only be used with threads started with QThread
I think using a timer is unnecessary, and confuses your example, so it is better to leave it out altogether. Instead, you should connect the started
signal of the worker thread to a run
method of the worker object. To simulate a long-running operation, you can use 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_()
Finally, note that you should always make signal connections after moving a worker object to a thread. The reasons for this are explained in this answer.
链接地址: http://www.djcxy.com/p/64498.html上一篇: 无法让Firefox或IE尊重最大
下一篇: QThread Windows没有响应