1. 程式人生 > 程式設計 >淺談PyQt5中非同步重新整理UI和Python多執行緒總結

淺談PyQt5中非同步重新整理UI和Python多執行緒總結

目前任務需要做一個介面程式,PyQt是非常方便的選擇,QT豐富的控制元件以及python方便的程式設計。近期遇到介面中執行一些後臺任務時介面卡死的情況,解決了在這裡記錄下。

PyQt

PyQt簡介

PyQt是Qt的python介面,PyQt的文件較少,但介面和函式可以完全參照Qt,繼承了Qt中大量的控制元件以及訊號機制,十分方便。以下簡介一個基本的PyQt程式。

- 需要匯入的類主要來自三個包

- from PyQt5.QtWidgets import 常用的控制元件

- PyQt5.QtCore 核心功能類,如QT,QThread,pyqtSignal

- PyQt5.QtGui UI類,如QFont

- 基礎的程式結構:

class Example(QWidget):
 def __init__(self):
  super()__init__()
  self.setupUI()

 def setupUI():
  self.show()
  pass
  # 設定UI
if __name__ == '__main__':
 app = QApplication(sys.argv) # 啟動app
 ex = Example() # 例項化一個自己派生的
 # 也可以例項化庫中的控制元件
 # q = QPushButton()
 # q.show()
 sys.exit(app.exec_())

總體來說:

1. 首先例項化APP

2. 例項化預定義控制元件或者自己派生自庫中的控制元件,記得呼叫show()函式

3. 執行並安全退出

Python中的多執行緒

python中的多執行緒使用較為方便,主要使用threading.Thread類:

1. 執行緒啟動使用start()函式

2. 如果需要等待執行緒執行使用join,這樣主執行緒會阻塞

實現方式一

直接傳入函式,啟動執行緒,可以傳入引數

import time,threading
def threadFunction():
 while True:
  print(11111)
  time.sleep()
# 用於命名,可以通過threading.current_thread().name獲得
t = threading.Thread(target=threadFunction,name='funciton')
# 如果執行緒有引數
t = threading.Thread(target=threadFunction,args=(),name='funciton')
t.start()

實現方式二

繼承Thread,重寫run方法

from threading import Thread
import time

class Example(Thread):
 def __init__(self):
  super().__init__()

 def run(self):
  while True:
   time.sleep(1)
   print(11111111)

if __name__ == '__main__':
 a = Example()
 a.start()
 a.join()
 print(222222222)

注意:

1. 使用join方法會讓主執行緒阻塞在這裡,等待子執行緒結束,在裡面可以設定阻塞的時間

2. a.setDaemon(True)在start前設定,可以保證在主執行緒終止時,子執行緒也終止

訊號機制

QT中的訊號機制能夠方便的編寫回調。

1. 很多控制元件都有預定的訊號如clicked,直接使用clicked.connect連線槽函式即可。

2. 繼承自Qt的類,然後自定義一個signal類變數,在例項連線訊號就可以了

class Example(QWidget):
 signal = pyqtSignal() # 括號裡填寫訊號傳遞的引數
 # 發射訊號
 def func(self):
  self.signal.emit()

# 使用訊號
a = Example()
a.signal.connect(callback)

# 槽函式
def callback():
 pass

UI重新整理

在介面中,通常用會有一些按鈕,點選後觸發事件,比如去下載一個檔案或者做一些操作,這些操作會耗時,如果不能及時結束,主執行緒將會阻塞,這樣介面就會出現未響應的狀態,因此必須使用多執行緒來解決這個問題。

注意:

1. PyQt5不能在子執行緒中重新整理執行緒,這樣會造成介面卡死,因此不能使用常規的多執行緒重新整理UI。

2. 但是又必須要實現子執行緒和主執行緒之間的通訊,否則無法得知任務是否完成。因此使用PyQt5中的QThread,這樣既可以使用訊號機制,又能夠使用多執行緒。

3. 當啟動多執行緒後,註冊訊號,槽函式為主執行緒中的函式,當任務完成後,發射訊號,在主執行緒中對UI進行更新。

注:由於需要註冊訊號,thread需要是繼承自QThread的類

class Example(QThread):
 signal = pyqtSignal() # 括號裡填寫訊號傳遞的引數
 def __init__(self):
  super().__init__()

 def __del__(self):
  self.wait()

 def run(self):
  # 進行任務操作
  self.signal.emit() # 發射訊號

# UI類中
def buttonClick(self)
 self.thread = Example()
 self.thread.signal.connect(self.callback)
 self.thread.start() # 啟動執行緒

def callbakc(self):
 pass

如有錯誤,歡迎指正~

以上這篇淺談PyQt5中非同步重新整理UI和Python多執行緒總結就是小編分享給大家的全部內容了,希望能給大家一個參考,也希望大家多多支援我們。