python PyQt5事件機制和定時器原理分析及用法詳解
PyQt5事件機制
PyQt為事件處理提供了兩種機制:高級的信號與槽機制,以及低級的事件處理機制。信號與槽可以說是對事件處理機制的高級封裝。事件機制更偏向于底層。
常見事件類型:
鍵盤事件:按鍵按下和松開。
鼠標(biāo)事件:鼠標(biāo)指針移動,鼠標(biāo)按下和松開。
拖放事件:用鼠標(biāo)進(jìn)行拖放。
滾輪事件:鼠標(biāo)滾輪滾動。
繪屏事件:重繪屏幕的某些部分。
定時事件:定時器到時。
焦點事件:鍵盤焦點移動。
進(jìn)入/離開事件:鼠標(biāo)指針移入Widget內(nèi),或者移出。
移動事件:Widget的位置改變。
大小改變事件:Widget的大小改變。
顯示/隱藏事件:Widget顯示和隱藏。
窗口事件:窗口是否為當(dāng)前窗口。
PyQt提供了如下5種事件處理和過濾方法(有弱到強):
重新實現(xiàn)事件函數(shù),比如mousePressEvent(),keyPressEvent()等等。
重新實現(xiàn)QObject.event()。
安裝時間過濾器。
在QApplication中安裝事件過濾器。
重新實現(xiàn)QAppliction的notifiy()方法。
PyQt5事件處理的API
PyQt5事件機制演練
import sys from PyQt5.Qt import * #通過繼承,重新notify方法 #事件會分發(fā)給對象里面的notify方法 class App(QApplication): #notify第一個參數(shù)是控件類型(事件接收者),第二個是事件類型 def notify(self, recevier, evt): #notify會監(jiān)控所有的事件,對事件進(jìn)行分發(fā)。為了打印鼠標(biāo)點擊按鈕產(chǎn)生的事件,我們進(jìn)行了過濾 #過濾事件接收者是按鈕,事件類型是鼠標(biāo)按鈕按下 #evt屬于QEvent類型。QEvent類型里面有個type方法,用來判斷事件類型 if recevier.inherits("QPushButton") and evt.type() == QEvent.MouseButtonPress: print(recevier, evt) #優(yōu)先調(diào)用子類notify方法,由于我們沒有寫具體功能,什么也做不了,會報錯,為了防止程序報錯,需要將父類的notify方法返回 #這行代碼就是負(fù)責(zé)分發(fā)的 return super().notify(recevier, evt) #寫個子類,過濾event事件類型 class Btn(QPushButton): #事件會分發(fā)給按鈕對象的event方法,event里面包含很多事件 def event(self, evt): if evt.type() == QEvent.MouseButtonPress: print(evt) #根據(jù)事件類型再次進(jìn)行分發(fā),根據(jù)不同事件調(diào)用不同事件函數(shù) return super().event(evt) #重寫鼠標(biāo)被按下事件函數(shù) def mousePressEvent(self, *args, **kwargs): print("鼠標(biāo)被按下了......") #返回父類鼠標(biāo)事件函數(shù),進(jìn)而發(fā)射信號給槽,調(diào)用槽函數(shù) #如果不返回,則不會發(fā)射信號給槽 return super().mousePressEvent(*args, **kwargs) app = App(sys.argv) window = QWidget() #設(shè)置主題 window.setWindowTitle("事件機制") btn = Btn(window) btn.setText("按鈕") btn.move(100, 100) def cao(): print("按鈕被點擊了") #按鍵按下 btn.pressed.connect(cao) window.show() sys.exit(app.exec_())
運行
點擊按鈕
可見事件被觸發(fā)
PyQt5定時器
在基于PyQt5的應(yīng)用程序開發(fā)過程中經(jīng)常會遇到一些需要循環(huán)執(zhí)行的任務(wù),即定時多長時間任務(wù)循環(huán)一次。
常用于數(shù)據(jù)庫定時更新、界面刷新、內(nèi)存清理、腳本任務(wù)運行、進(jìn)度條等需要定時更新的程序段,小到某一參數(shù)的定時更新,大到整個線程任務(wù)的更新、程序段的循環(huán)定時執(zhí)行。
本文將詳細(xì)介紹如何在PyQt5中使用定時器,包括定時器的基本原理、創(chuàng)建和使用定時器的方法以及一些實際應(yīng)用案例。
定時器的操作方法有兩種
方法一:利用每個對象包含的timerEvent函數(shù)
方法二:利用定時器模塊 需要 from PyQt5.QtCore import QTimer
(1)利用每個對象包含的timerEvent函數(shù)
API介紹已經(jīng)案例演示
# 0. 導(dǎo)入需要的包和模塊 from PyQt5.Qt import * import sys #自定義一個類繼承QObejct # class MyObject(QObject): # def timerEvent(self, evt): #重寫對象的定時器函數(shù) # print(evt, "1") #自定義個類繼承QLabel,可以重寫父類方法,尤其是timerEvent對象的定時器函數(shù) class MyLabel(QLabel): #增加參數(shù)接收*args, **kwargs def __init__(self, *args, **kwargs): # 當(dāng)我們繼承某個類時,需要調(diào)用父類構(gòu)造方法 #加載父類初始化方法 super().__init__(*args, **kwargs) self.setText("10") self.move(235, 235) self.setStyleSheet("font-size: 28px;") #設(shè)置標(biāo)簽上展示的初始數(shù)字 def setSec(self, sec): self.setText(str(sec)) def startMyTimer(self, ms): #可以創(chuàng)建多個,每個startTimer返回的id不同 #每個一定的時間,就會自動執(zhí)行對象中的timerEvent函數(shù) #參數(shù)1 間隔時間,單位毫秒 self.timer_id = self.startTimer(ms,timerType=Qt.PreciseTimer) #啟動對象定時器函數(shù) def timerEvent(self, *args, **kwargs): print("倒計時進(jìn)行中") # 1. 獲取當(dāng)前的標(biāo)簽的內(nèi)容 current_sec = int(self.text()) current_sec -= 1 #將內(nèi)容以字符串形式展示,整形數(shù)據(jù)沒法直接放進(jìn)來 self.setText(str(current_sec)) #當(dāng)前數(shù)字減為0時,停止定時器 if current_sec == 0: print("倒計時停止") # 釋放對象的定時器函數(shù) self.killTimer(self.timer_id) class MyWidget(QWidget): def startMyTimer(self, ms): #可以創(chuàng)建多個,每個startTimer返回的id不同 #每個一定的時間,就會自動執(zhí)行對象中的timerEvent函數(shù) #參數(shù)1 間隔時間,單位毫秒 self.widget_id = self.startTimer(ms,timerType=Qt.PreciseTimer) #啟動對象定時器函數(shù) def timerEvent(self, *args, **kwargs): #獲取當(dāng)前窗口的高和寬 current_w = self.width() current_h = self.height() #定時器每執(zhí)行一次,窗口長和高都加10 self.resize(current_w + 10, current_h + 10) print("當(dāng)前窗口高度", current_h) #設(shè)置當(dāng)前窗口高度達(dá)到550時,停止定時器 if current_h == 550: print("widget停止") # 釋放對象的定時器函數(shù) self.killTimer(self.widget_id) if __name__ == '__main__': # 1. 創(chuàng)建一個應(yīng)用程序?qū)ο? app = QApplication(sys.argv) # 2. 控件的操作 # 2.1 創(chuàng)建控件 window = MyWidget() # 2.2 設(shè)置控件 window.setWindowTitle("QObject定時器的使用") window.resize(500, 500) window.startMyTimer(1000) #創(chuàng)建第二個控件 label = MyLabel(window) label.setSec(10) label.startMyTimer(500) # 2.3 展示控件 window.show() # 3. 應(yīng)用程序的執(zhí)行, 進(jìn)入到消息循環(huán) sys.exit(app.exec_())
運行
當(dāng)?shù)竭_(dá)臨界值,定時器停止
(2)利用定時器模塊QTimer
需要導(dǎo)包 from PyQt5.QtCore import QTimer
QTimer 的事件可以通過 QTimer.timeout.connect() 信號槽綁定到對應(yīng)的處理函數(shù)上。
例如,在下面的示例中,定義了一個 onTimer() 函數(shù),每當(dāng)定時器時間到達(dá)時,就會執(zhí)行這個函數(shù)。
要啟動 QTimer 定時器,需要調(diào)用 QTimer.setInterval() 方法,并傳入時間間隔,單位為毫秒(ms)。
例如,傳入 1000 表示每隔 1000 毫秒(即 1 秒)會觸發(fā)一次 operate()。需要注意的是,定時器不僅僅是觸發(fā)一次,而是持續(xù)按照設(shè)定的時間間隔觸發(fā),直到調(diào)用 QTimer.stop() 方法停止。
import sys from PyQt5.Qt import * class win(QWidget): #創(chuàng)建一個類,為了集成控件 # 增加參數(shù)接收*args, **kwargs def __init__(self, *args, **kwargs): # 當(dāng)我們繼承某個類時,需要調(diào)用父類構(gòu)造方法 super().__init__(*args, **kwargs) self.setWindowTitle('定時器的使用') self.resize(300,300) self.num=0 self.setup_ui() def setup_ui(self): #添加個標(biāo)簽,初始化標(biāo)簽 self.lable = QLabel(self) self.lable.move(120,120) self.lable.setStyleSheet("font-size: 28px;") self.timer = QTimer(self) # 初始化一個定時器 # 設(shè)置計時間隔;單位毫秒 self.timer.setInterval(1000) self.timer.timeout.connect(self.operate) # 每次計時到時間時發(fā)出信號 #啟動定時器,也可以在這里設(shè)置時間間隔,例如:self.timer.start(1000) 表示每秒執(zhí)行一次 self.timer.start() #定時器要執(zhí)行的動作 def operate(self): self.num=self.num+1 print(self.num) #動態(tài)設(shè)置標(biāo)簽顯示數(shù)字 self.lable.setText(str(self.num)) #設(shè)置定時器停止閾值 if self.num == 5: print("計時停止") self.timer.stop() if __name__=='__main__': app=QApplication(sys.argv) #創(chuàng)建應(yīng)用 window=win() window.show() sys.exit(app.exec_())
運行
當(dāng)num數(shù)值增加到5時,定時器停止
以上就是python PyQt5事件機制和定時器原理分析及用法詳解的詳細(xì)內(nèi)容,更多關(guān)于PyQt5事件機制和定時器的資料請關(guān)注腳本之家其它相關(guān)文章!
相關(guān)文章
通過Python 獲取Android設(shè)備信息的輕量級框架
今天跟大家分享一下,如何通過Python實現(xiàn)一個輕量級的庫來獲取電腦上連接的Android設(shè)備信息,需要的朋友參考下吧2017-12-12利用 Python 實現(xiàn)多任務(wù)進(jìn)程
這篇文章主要介紹如何利用 Python 實現(xiàn)多任務(wù)進(jìn)程,正在執(zhí)行的程序,由程序、數(shù)據(jù)和進(jìn)程控制塊組成,是正在執(zhí)行的程序,程序的一次執(zhí)行過程,是資源調(diào)度的基本單位。下面就來詳細(xì)介紹改內(nèi)容,需要的朋友可以參考一下2021-10-10使用APScheduler3.0.1 實現(xiàn)定時任務(wù)的方法
今天小編就為大家分享一篇使用APScheduler3.0.1 實現(xiàn)定時任務(wù)的方法,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧2019-07-07淺析Python與Java和C之間有哪些細(xì)微區(qū)別
這篇文章主要介紹了Python與Java和C之間有哪些細(xì)微區(qū)別,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2022-08-08