在pyqt5中我們通常需要在子線程中處理耗時操作如網絡請求,在主線程中更新UI界面,下面是一個簡單的例子,運作界面如下
# -*- coding: utf-8 -*-
import sys
from PyQt5.QtCore import QThread, pyqtSignal
from PyQt5.QtGui import QIcon, QCloseEvent
from PyQt5.QtWidgets import *
class MyThread(QThread):
# 定義一個傳輸 int類型的信号
send_singal = pyqtSignal(int)
def run(self):
for i in range(1, 5):
print("current id is: ", self.currentThreadId())
self.send_singal.emit(i)
QThread.sleep(1)
class Window(QWidget):
def __init__(self,*args, **kwargs):
super(Window, self).__init__(*args, **kwargs)
# 設定寬高
self.resize(600, 400)
# 視窗移動到指定位置
self.move(660,300)
# 設定标題
self.setWindowTitle("标哥測試")
# 設定logo
# self.setWindowIcon(QIcon("logo.png"))
# 初始化UI界面的控件
self.setUI()
# 初始化事件
self.intilogic()
def setUI(self):
self.layout = QVBoxLayout()
self.progress = QProgressBar()
self.progress.setRange(0, 100)
print(self.progress.width())
self.button = QPushButton("點選開始線程")
self.button.clicked.connect(self.start)
self.layout.addWidget(self.progress)
self.layout.addWidget(self.button)
self.setLayout(self.layout)
def intilogic(self):
# 建立子線程并和目前視窗綁定
self.thread = MyThread(self)
# 完成循環後删除子線程
self.thread.finished.connect(self.thread.deleteLater)
self.thread.send_singal.connect(self.change_value)
self.button.clicked.connect(self.start)
def change_value(self, value):
# 設定進度條
self.progress.setValue(value)
def start(self):
print('目前主線程ID: ', int(QThread.currentThreadId()))
# 線程開啟後再次點選是沒有用的,也不會再次重新開始線程
# 但是當線程運作完畢之後,由于上面調用了
# self.thread.deleteLater 是以 在子線程運作完畢之後再次點選運作這段代碼會報錯,需要處理
try:
self.thread.start()
except:
print("子線程開啟失敗")
# 視窗的關閉事件
def closeEvent(self, a0: QCloseEvent):
print("關閉")
super(Window, self).closeEvent(a0)
if __name__ == "__main__":
app = QApplication(sys.argv)
window = Window()
window.show()
sys.exit(app.exec_())