一、背景
在進行開發的時候,比如請求網頁,資源下載等問題的時候 ,需要使用多線程對程序進行處理。一是避免程序假死,二是提高用戶體驗,增強程序健壯性。
二、方法
通過繼承Qthread的方法,重寫run函數進行處理。處理的流程如下圖
2.1 構建線程方法
通過繼承Qthread編寫自己的線程方法
# 這里編寫一個請求網站資源的多線程方法
class Thread(QThread): # 設置信號量,用於線程返回信息的處理
signal = pyqtSignal(str) def __init__(self, url=None): super(Thread, self).__init__() # 實現參數的傳遞
self.url = url def run(self): """ 重構的run函數 """
# 需要多線程的方法,這里是一個視頻下載的方法
get_url(self.url) # 將線程處理的信息返回給調用的槽函數,可以實現加鎖和解鎖的目的
self.signal.emit()
2.2 線程方法的時候
# 在pyqt中使用剛剛創建的線程方法 # 核心部分 # 注:這里使用oop的編程思想,因此輸入的文本直接通過文本框的方法獲取到輸入的結果
def button_ui(self): # 確定按鈕按鈕出發線程事件
self.qbtn.clicked.connect(self.event_confirm) # 按鈕布局
self.qbtn.resize(self.qbtn.sizeHint()) self.qbtn.move(189, 400) # 函數事件
def event_confirm(self): # 設置按鈕不可用,鎖定狀態
self.qbtn.setEnabled(False) # 獲取參數
content_text = self.qtb.toPlainText() self.thread.url = content_text # 啟動線程
self.thread.start() # 處理完之后的回調,
self.thread.signal.connect(self.set_btn) def set_btn(self): # 將按鈕標簽的狀態回滾
self.qbtn.setEnabled(True)
2.3 實際例子
這里實現一個從網站下載視頻的例子,總代碼如下:
import sys from PyQt5.QtCore import QCoreApplication, QThread, pyqtSignal from PyQt5.QtWidgets import QApplication, QWidget, QPushButton, QLabel, QPlainTextEdit from PyQt5.QtGui import QIcon class Thread(QThread): signal = pyqtSignal(str) def __init__(self, url=None): super(Thread, self).__init__() self.url = url def run(self):
# 線程使用的方法 get_url(self.url) self.signal.emit() class Example(QWidget): def __init__(self): super(QWidget, self).__init__() self.qbtn = QPushButton('確定', self) self.thread = Thread() self.qtb = QPlainTextEdit(self, ) self.init_ui() # 界面繪制交給InitUi方法
def button_ui(self): # 退出按鈕
qbtn = QPushButton('退出', self) qbtn.clicked.connect(QCoreApplication.instance().quit) qbtn.resize(qbtn.sizeHint()) qbtn.move(689, 400) # 標簽
qlab = QLabel("輸入網址", self) qlab.resize(qlab.sizeHint()) qlab.move(200, 50) # 輸入框
self.qtb.resize(self.qtb.sizeHint()) self.qtb.move(260, 70) # 確定按鈕
self.qbtn.clicked.connect(self.event_confirm) self.qbtn.resize(self.qbtn.sizeHint()) self.qbtn.move(189, 400) def event_confirm(self): self.qbtn.setEnabled(False) content_text = self.qtb.toPlainText() self.thread.url = content_text print(self.thread.url) self.thread.start() # print(content_text)
self.thread.signal.connect(self.set_btn) # content_text = self.qtb.toPlainText()
# self.thread.trigger.connect(get_url(content_text))
# self.thread.start()
def set_btn(self): self.qbtn.setEnabled(False) def init_ui(self): self.button_ui() # 設置窗口的位置和大小
self.setGeometry(510, 297, 863, 473) # 設置窗口的標題
self.setWindowTitle('視頻獲取') # 設置窗口的圖標,引用當前目錄下的web.png圖片
self.setWindowIcon(QIcon('web.png')) # 顯示窗口
self.show() if __name__ == '__main__': # 創建應用程序和對象
app = QApplication(sys.argv) ex = Example() sys.exit(app.exec_())
三、總結
多線程的使用對於實際的開發很重要,這里列舉了一個實際的例子,可以據此寫出更加復雜的功能。
參考
這里列舉一些學習過程中有用的資源。