淺談PyQt5中異步刷新UI和Python多線程總結(jié)
目前任務(wù)需要做一個(gè)界面程序,PyQt是非常方便的選擇,QT豐富的控件以及python方便的編程。近期遇到界面中執(zhí)行一些后臺(tái)任務(wù)時(shí)界面卡死的情況,解決了在這里記錄下。
PyQt
PyQt簡(jiǎn)介
PyQt是Qt的python接口,PyQt的文檔較少,但接口和函數(shù)可以完全參照Qt,繼承了Qt中大量的控件以及信號(hào)機(jī)制,十分方便。以下簡(jiǎn)介一個(gè)基本的PyQt程序。
- 需要導(dǎo)入的類(lèi)主要來(lái)自三個(gè)包
- from PyQt5.QtWidgets import 常用的控件
- PyQt5.QtCore 核心功能類(lèi),如QT,QThread,pyqtSignal
- PyQt5.QtGui UI類(lèi),如QFont
- 基礎(chǔ)的程序結(jié)構(gòu):
class Example(QWidget): def __init__(self): super()__init__() self.setupUI() def setupUI(): self.show() pass # 設(shè)置UI if __name__ == '__main__': app = QApplication(sys.argv) # 啟動(dòng)app ex = Example() # 實(shí)例化一個(gè)自己派生的 # 也可以實(shí)例化庫(kù)中的控件 # q = QPushButton() # q.show() sys.exit(app.exec_())
總體來(lái)說(shuō):
1. 首先實(shí)例化APP
2. 實(shí)例化預(yù)定義控件或者自己派生自庫(kù)中的控件,記得調(diào)用show()函數(shù)
3. 執(zhí)行并安全退出
Python中的多線程
python中的多線程使用較為方便,主要使用threading.Thread類(lèi):
1. 線程啟動(dòng)使用start()函數(shù)
2. 如果需要等待線程執(zhí)行使用join,這樣主線程會(huì)阻塞
實(shí)現(xiàn)方式一
直接傳入函數(shù),啟動(dòng)線程,可以傳入?yún)?shù)
import time, threading def threadFunction(): while True: print(11111) time.sleep() # 用于命名,可以通過(guò)threading.current_thread().name獲得 t = threading.Thread(target=threadFunction, name='funciton') # 如果線程有參數(shù) t = threading.Thread(target=threadFunction, args=(), name='funciton') t.start()
實(shí)現(xiàn)方式二
繼承Thread,重寫(xiě)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方法會(huì)讓主線程阻塞在這里,等待子線程結(jié)束,在里面可以設(shè)置阻塞的時(shí)間
2. a.setDaemon(True)在start前設(shè)置,可以保證在主線程終止時(shí),子線程也終止
信號(hào)機(jī)制
QT中的信號(hào)機(jī)制能夠方便的編寫(xiě)回調(diào)。
1. 很多控件都有預(yù)定的信號(hào)如clicked,直接使用clicked.connect連接槽函數(shù)即可。
2. 繼承自Qt的類(lèi),然后自定義一個(gè)signal類(lèi)變量,在實(shí)例連接信號(hào)就可以了
class Example(QWidget): signal = pyqtSignal() # 括號(hào)里填寫(xiě)信號(hào)傳遞的參數(shù) # 發(fā)射信號(hào) def func(self): self.signal.emit() # 使用信號(hào) a = Example() a.signal.connect(callback) # 槽函數(shù) def callback(): pass
UI刷新
在界面中,通常用會(huì)有一些按鈕,點(diǎn)擊后觸發(fā)事件,比如去下載一個(gè)文件或者做一些操作,這些操作會(huì)耗時(shí),如果不能及時(shí)結(jié)束,主線程將會(huì)阻塞,這樣界面就會(huì)出現(xiàn)未響應(yīng)的狀態(tài),因此必須使用多線程來(lái)解決這個(gè)問(wèn)題。
注意:
1. PyQt5不能在子線程中刷新線程,這樣會(huì)造成界面卡死,因此不能使用常規(guī)的多線程刷新UI。
2. 但是又必須要實(shí)現(xiàn)子線程和主線程之間的通信,否則無(wú)法得知任務(wù)是否完成。因此使用PyQt5中的QThread,這樣既可以使用信號(hào)機(jī)制,又能夠使用多線程。
3. 當(dāng)啟動(dòng)多線程后,注冊(cè)信號(hào),槽函數(shù)為主線程中的函數(shù),當(dāng)任務(wù)完成后,發(fā)射信號(hào),在主線程中對(duì)UI進(jìn)行更新。
注:由于需要注冊(cè)信號(hào),thread需要是繼承自QThread的類(lèi)
class Example(QThread): signal = pyqtSignal() # 括號(hào)里填寫(xiě)信號(hào)傳遞的參數(shù) def __init__(self): super().__init__() def __del__(self): self.wait() def run(self): # 進(jìn)行任務(wù)操作 self.signal.emit() # 發(fā)射信號(hào) # UI類(lèi)中 def buttonClick(self) self.thread = Example() self.thread.signal.connect(self.callback) self.thread.start() # 啟動(dòng)線程 def callbakc(self): pass
如有錯(cuò)誤,歡迎指正~
以上這篇淺談PyQt5中異步刷新UI和Python多線程總結(jié)就是小編分享給大家的全部?jī)?nèi)容了,希望能給大家一個(gè)參考,也希望大家多多支持腳本之家。
相關(guān)文章
Python中sklearn實(shí)現(xiàn)交叉驗(yàn)證示例分析
這篇文章主要介紹了Python中sklearn實(shí)現(xiàn)交叉驗(yàn)證,本文python的版本為3.8,各個(gè)版本之間函數(shù)名字略有不同,但是原理都是一樣的,集成開(kāi)發(fā)環(huán)境使用的是Anaconda的Spyder,需要的朋友可以參考下2023-08-08Python腳本實(shí)現(xiàn)集群檢測(cè)和管理功能
這篇文章主要介紹了Python腳本實(shí)現(xiàn)集群檢測(cè)和管理功能,本文講解了實(shí)現(xiàn)想法、開(kāi)發(fā)工具選擇、經(jīng)驗(yàn)分享、代碼示例等內(nèi)容,需要的朋友可以參考下2015-03-03python使用Plotly繪圖工具繪制散點(diǎn)圖、線形圖
這篇文章主要為大家詳細(xì)介紹了python使用Plotly繪圖工具繪制散點(diǎn)圖、線形圖,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2019-04-04詳解pycharm2020.1.1專(zhuān)業(yè)版安裝指南(推薦)
這篇文章主要介紹了pycharm2020.1.1專(zhuān)業(yè)版安裝指南,本文給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2020-08-08python+tkinter實(shí)現(xiàn)學(xué)生管理系統(tǒng)
這篇文章主要為大家詳細(xì)介紹了python+tkinter實(shí)現(xiàn)學(xué)生管理系統(tǒng),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2019-08-08django實(shí)現(xiàn)web接口 python3模擬Post請(qǐng)求方式
今天小編就為大家分享一篇django實(shí)現(xiàn)web接口 python3模擬Post請(qǐng)求方式,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧2019-11-11