一、
當我們設計的界面在處理比較長時間的任務時,就會出現阻塞,出現程序未響應,導致程序停止的情況,例如這個百度圖片下載器。
所以我們應把主線程與工作線程分離,以免主循環阻塞,造成程序停止響應
二、例子
from PyQt5.QtCore import *
from PyQt5.QtGui import *
from PyQt5.QtWidgets import *
import sys
class Example(QWidget):
def __init__(self):
super().__init__()
self.t = 0
window = QWidget()
vbox = QVBoxLayout(window)
#vbox = QVBoxLayout(window)
lcdNumber = QLCDNumber()
button = QPushButton("測試")
vbox.addWidget(lcdNumber)
vbox.addWidget(button)
self.timer = QTimer()
button.clicked.connect(self.work)
self.timer.timeout.connect(self.setTime)
self.setLayout(vbox)
self.show()
def setTime(self):
self.t += 1
self.lcdNumber.display(self.t)
def work(self):
self.timer.start(10000)
for i in range(200000000):
pass
self.timer.stop()
if __name__ == "__main__":
app = QApplication(sys.argv)
th = Example()
sys.exit(app.exec_())
運行這個程序,當我們點擊測試,進行較長時間的任務時,程序就無法選中了,最終停止運行。
三、多線程
下面用多線寫法解決該問題
from PyQt5.QtCore import *
from PyQt5.QtGui import *
from PyQt5.QtWidgets import *
import sys
class Example(QWidget):
def __init__(self):
super().__init__()
self.t = 0
window = QWidget()
vbox = QVBoxLayout(window)
#vbox = QVBoxLayout(window)
self.lcdNumber = QLCDNumber()
button = QPushButton("測試")
vbox.addWidget(self.lcdNumber)
vbox.addWidget(button)
self.timer = QTimer()
button.clicked.connect(self.Work)
self.timer.timeout.connect(self.CountTime)
self.setLayout(vbox)
self.show()
def CountTime(self):
self.t += 1
self.lcdNumber.display(self.t)
def Work(self):
self.timer.start(1000)
self.thread = RunThread()
self.thread.start()
self.thread.trigger.connect(self.TimeStop)
def TimeStop(self):
self.timer.stop()
print("運行結束用時",self.lcdNumber.value())
self.t = 0
class RunThread(QThread):
# python3,pyqt5與之前的版本有些不一樣
# 通過類成員對象定義信號對象
# _signal = pyqtSignal(str)
trigger = pyqtSignal()
def __init__(self, parent=None):
super(RunThread, self).__init__()
def __del__(self):
self.wait()
def run(self):
# 處理你要做的業務邏輯,這里是通過一個回調來處理數據,這里的邏輯處理寫自己的方法
# wechat.start_auto(self.callback)
# self._signal.emit(msg); 可以在這里寫信號煥發
for i in range(203300030):
pass
self.trigger.emit()
# self._signal.emit(msg)
def callback(self, msg):
# 信號煥發,我是通過我封裝類的回調來發起的
# self._signal.emit(msg)
pass
if __name__ == "__main__":
app = QApplication(sys.argv)
th = Example()
sys.exit(app.exec_())
從此以后,我們可以開始寫很多應用了