经常会遇到一段需要持续运行的程序,在运行过程中会定时或不定时的数据一些信息。在PyQt5中界面会一直等到程序结束后一次性显示所有信息,同时整个界面就会卡住。QThread 模块就是用来解决这个问题的。
书中举得例子是实时显示时间,就不多说了。我自己也写了一个例子加强理解。UI界面使用designer做好了,用pyuic5转换成的py文件,就是所谓的界面和业务分离的操作。
先上界面代码:

1 from PyQt5 import QtCore, QtGui, QtWidgets 2 3 4 class Ui_MainWindow(object): 5 def setupUi(self, MainWindow): 6 MainWindow.setObjectName("MainWindow") 7 MainWindow.resize(258, 340) 8 self.centralwidget = QtWidgets.QWidget(MainWindow) 9 self.centralwidget.setObjectName("centralwidget") 10 self.pushButton = QtWidgets.QPushButton(self.centralwidget) 11 self.pushButton.setGeometry(QtCore.QRect(150, 40, 75, 23)) 12 self.pushButton.setObjectName("pushButton") 13 self.textBrowser = QtWidgets.QTextBrowser(self.centralwidget) 14 self.textBrowser.setGeometry(QtCore.QRect(0, 110, 251, 221)) 15 self.textBrowser.setObjectName("textBrowser") 16 17 MainWindow.setCentralWidget(self.centralwidget) 18 19 self.retranslateUi(MainWindow) 20 QtCore.QMetaObject.connectSlotsByName(MainWindow) 21 22 def retranslateUi(self, MainWindow): 23 _translate = QtCore.QCoreApplication.translate 24 MainWindow.setWindowTitle(_translate("MainWindow", "MainWindow")) 25 self.pushButton.setText(_translate("MainWindow", "PushButton"))
再上业务代码:

1 import sys 2 import time 3 from PyQt5.QtWidgets import QApplication ,QMainWindow 4 from PyQt5.QtCore import pyqtSignal, QObject, QThread 5 from win_signal_slot import * 6 7 8 class BackendThread(QThread): 9 update_date = pyqtSignal(str) 10 11 def run(self): 12 for i in range(100): 13 if i % 3 == 0: 14 self.update_date.emit('%d发送成功' % i) 15 time.sleep(0.1) 16 self.update_date.emit('程序执行结束。') 17 18 19 class MainWindow(QMainWindow, Ui_MainWindow): 20 21 def __init__(self, parent=None): 22 super(MainWindow, self).__init__(parent) 23 self.setupUi(self) 24 25 self.pushButton.clicked.connect(self.run) 26 27 28 def run(self): 29 self.textBrowser.setText('程序开始执行...') 30 #执行后台的线程 31 self.backend = BackendThread() 32 self.backend.update_date.connect(self.show_msg) 33 self.backend.start() 34 35 def show_msg(self,data): 36 self.textBrowser.append(data) 37 38 if __name__ == '__main__': 39 app = QApplication(sys.argv) 40 win = MainWindow() 41 win.show() 42 sys.exit(app.exec_())
页面展示出来就是这个样: