资料
pyqt5 使用多线程避免程序假死 - 蔚蓝色の天空 - 博客园
https://www.cnblogs.com/future-dream/p/14749132.html
需求
在下面这样一个界面,我们希望实现点击按钮1
之后,在标签上依次打印 1,2,3,4,…
下面的代码无法实现,因为单线程的原因,只会在标签上打印最后一个数字,且等待时间会出现意思崩溃的假象,因此我们需要使用多线程。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27
| from PyQt5.Qt import QApplication, QWidget, QPushButton, QLabel import sys import time
class MyWinClass(QWidget): def __init__(self): super().__init__()
self.btn_1 = QPushButton('按钮1', self) self.btn_1.move(120, 80) self.btn_1.clicked.connect(self.btn_1_click)
self.label_1 = QLabel('标签啊标签', self) self.label_1.move(120, 120)
def btn_1_click(self): for ii in range(1000): time.sleep(1) self.label_1.setText(str(ii))
if __name__ == "__main__": app = QApplication(sys.argv) w = MyWinClass() w.show() sys.exit(app.exec_())
|
QThread
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42
| from PyQt5.Qt import QApplication, QWidget, QPushButton, QLabel from PyQt5.Qt import QThread, pyqtSignal import sys import time
class Thread_1(QThread): signal = pyqtSignal(str)
def run(self): for ii in range(1000): time.sleep(1) self.signal.emit(str(ii))
class MyWinClass(QWidget): def __init__(self): super().__init__()
self.btn_1 = QPushButton('按钮1', self) self.btn_1.move(120, 80) self.btn_1.clicked.connect(self.btn_1_click)
self.label_1 = QLabel('标签啊标签', self) self.label_1.move(120, 120)
def btn_1_click(self): self.thread = Thread_1() self.thread.signal.connect(self.show_msg) self.thread.start()
def show_msg(self, str00): """ 处理线程信号的函数 """ self.label_1.setText(str00)
if __name__ == "__main__": app = QApplication(sys.argv) w = MyWinClass() w.show() sys.exit(app.exec_())
|
- 建立一个继承 QThread 的类 Thread_1,重写 run 函数。在 run 函数中编写耗时或者单线程不便处理的函数,让
run
函数执行完毕后发出一个信号 signal,在MyWinClass
里面编写处理这个信号的函数。
- 整个流程的逻辑是:(1) 在主程序中实例化一个 Thread_1 类的线程对象
self.thread
,(2) 绑定self.thread
的槽的处理函数, (3) 执行self.thread.start()
,就会执行self.thread.run()
,然后发出信号,调用处理槽的函数。
- QThread 缺点是不能自己选择终止进程,也可能是我没找到。对于间隔执行的任务,建议使用计时器Qtimer,可以自己选择终止任务。
Qtimer
1 2 3 4 5 6 7 8 9 10 11 12
| from PyQt5.QtCore import QTime
self.time = QTimer(self) self.time.timeout.connect(self.YourFunction)
self.time.start(1000)
self.time.stop()
|