詳解PyQt5?事件處理機(jī)制
PyQt5 事件處理機(jī)制
PyQt為事件處理提供了兩種機(jī)制:高級(jí)的信號(hào)與槽機(jī)制,以及低級(jí)的事件處理機(jī)制。信號(hào)與槽可以說是對(duì)事件處理機(jī)制的高級(jí)封裝。
常見事件類型:
- 鍵盤事件:按鍵按下和松開。
- 鼠標(biāo)事件:鼠標(biāo)指針移動(dòng),鼠標(biāo)按下和松開。
- 拖放事件:用鼠標(biāo)進(jìn)行拖放。
- 滾輪事件:鼠標(biāo)滾輪滾動(dòng)。
- 繪屏事件:重繪屏幕的某些部分。
- 定時(shí)事件:定時(shí)器到時(shí)。
- 焦點(diǎn)事件:鍵盤焦點(diǎn)移動(dòng)。
- 進(jìn)入/離開事件:鼠標(biāo)指針移入Widget內(nèi),或者移出。
- 移動(dòng)事件:Widget的位置改變。
- 大小改變事件:Widget的大小改變。
- 顯示/隱藏事件:Widget顯示和隱藏。
- 窗口事件:窗口是否為當(dāng)前窗口。
PyQt提供了如下5種事件處理和過濾方法(有弱到強(qiáng)):
- 重新實(shí)現(xiàn)事件函數(shù),比如mousePressEvent(),keyPressEvent()等等。
- 重新實(shí)現(xiàn)QObject.event()。
- 安裝時(shí)間過濾器。
- 在QApplication中安裝事件過濾器。
- 重新實(shí)現(xiàn)QAppliction的notifiy()方法。
import sys from PyQt5.QtWidgets import (QApplication, QMenu, QWidget) from PyQt5.QtCore import (QEvent, QTimer, Qt) from PyQt5.QtGui import QPainter class MyEventDemoWindow(QWidget): def __init__(self, parent=None): super(MyEventDemoWindow, self).__init__(parent) self.justDoubleClikcked = False self.key = "" self.text = "" self.message = "" self.resize(400, 300) self.move(100, 100) self.setWindowTitle("Events Demo 1") QTimer.singleShot(1000, self.giveHelp) def giveHelp(self): self.text = "請(qǐng)點(diǎn)擊這里觸發(fā)追蹤鼠標(biāo)功能" self.update() # 重繪事件,也就是除非paintEvent函數(shù) # 重新實(shí)現(xiàn)關(guān)閉事件 def closeEvent(self, event): print("Closed") # 重新實(shí)現(xiàn)上下文菜單事件 def contextMenuEvent(self, event): menu = QMenu(self) oneAction = menu.addAction("&One") twoAction = menu.addAction("&Two") oneAction.triggered.connect(self.one) twoAction.triggered.connect(self.two) if not self.message: menu.addSeparator() threeAction = menu.addAction("&Three") threeAction.triggered.connect(self.three) menu.exec_(event.globalPos()) def one(self): self.message = "Menu Option One" self.update() def two(self): self.message = "Menu Option Two" self.update() def three(self): self.message = "Menu Option Three" self.update() '''重新實(shí)現(xiàn)繪制事件''' def paintEvent(self, event): text = self.text i = text.find("\n\n") if i >= 0: text = text[0:i] if self.key: text += "\n\n你按下了:{0}".format(self.key) painter = QPainter(self) painter.setRenderHint(QPainter.TextAntialiasing) painter.drawText(self.rect(), Qt.AlignCenter, text) # 繪制文本 if self.message: painter.drawText(self.rect(), Qt.AlignBottom | Qt.AlignHCenter, self.message) QTimer.singleShot(5000, self.clearMessage) QTimer.singleShot(5000, self.update) # 清空文本信息槽函數(shù) def clearMessage(self): self.message = "" # 重新實(shí)現(xiàn)調(diào)整窗口大小事件 def resizeEvent(self, event): self.text = "調(diào)整窗口大小為: QSize({0}, {1})".format(event.size().width(), event.size().height()) self.update() # 重新實(shí)現(xiàn)鼠標(biāo)釋放事件 def mouseReleaseEvent(self, event) -> None: if self.justDoubleClikcked: self.justDoubleClikcked = False else : self.setMouseTracking(not self.hasMouseTracking()) # 單擊鼠標(biāo) if self.hasMouseTracking(): self.text = "你釋放了鼠標(biāo) 開啟鼠標(biāo)跟蹤功能.\n\n" + \ "請(qǐng)移動(dòng)鼠標(biāo)\n\n" + \ "單擊鼠標(biāo)可以關(guān)閉這個(gè)功能" else: self.text = "你釋放了鼠標(biāo) 關(guān)閉鼠標(biāo)跟蹤功能" + \ "單擊鼠標(biāo)可以開啟這個(gè)功能" self.update() '''重新實(shí)現(xiàn)鼠標(biāo)移動(dòng)事件''' def mouseMoveEvent(self, event): if not self.justDoubleClikcked: globalPos = self.mapToGlobal(event.pos())# 將窗口坐標(biāo)轉(zhuǎn)換為屏幕坐標(biāo) self.text = """鼠標(biāo)位置: 窗口坐標(biāo)為:QPoint({0}, {1}) 屏幕坐標(biāo)為:QPoint({2}, {3})""".format(event.pos().x(), event.pos().y(), globalPos.x(), globalPos.y()) self.update() '''重新實(shí)現(xiàn)鼠標(biāo)雙擊事件''' def mouseDoubleClickEvent(self, event): self.justDoubleClikcked = True self.text = "你雙擊了鼠標(biāo)" self.update() def mousePressEvent(self, event): self.text = "你按下了鼠標(biāo)" self.update() def keyPressEvent(self, event): self.text = "你按下了按鍵" self.key = "" if event.key() == Qt.Key_Home: self.key = "Home" elif event.key() == Qt.Key_End: self.key = "End" elif event.key() == Qt.Key_PageUp: if event.modifiers() & Qt.ControlModifier: self.key = "Ctrl + Page Up" else: self.key = "Page Up" elif event.key() == Qt.Key_PageDown: if event.modifiers() & Qt.ControlModifier: self.key = "Ctrl + Key_PageDown" else: self.key = "Key_PageDown" elif Qt.Key_A <= event.key() <= Qt.Key_Z: if event.modifiers() & Qt.ShiftModifier: self.key = "Shift+" self.key += event.text() if self.key: self.key = self.key self.update() else: QWidget.keyPressEvent(self, event) def keyReleaseEvent(self, event): self.text = "你釋放了按鍵" self.update() '''重新實(shí)現(xiàn)event,捕獲Tab鍵''' def event(self, event): if (event.type() == QEvent.KeyPress and event.key() == Qt.Key_Tab): self.key = "在event() 中捕獲Tab鍵" self.update() return True # 返回True表示本次事件已經(jīng)執(zhí)行處理 else: return QWidget.event(self, event) # 繼續(xù)處理事件 if __name__ == "__main__": app = QApplication(sys.argv) win = MyEventDemoWindow() win.show() sys.exit(app.exec_())
import sys from PyQt5.QtGui import * from PyQt5.QtCore import * from PyQt5.QtWidgets import * class EventFilter(QDialog): def __init__(self, parent=None): super(EventFilter, self).__init__(parent) self.setWindowTitle("事件過濾器") self.label1 = QLabel("請(qǐng)點(diǎn)擊") self.label2 = QLabel("請(qǐng)點(diǎn)擊") self.label3 = QLabel("請(qǐng)點(diǎn)擊") self.LabelState = QLabel("test") self.image1 = QImage("pyqt5/images/cartoon1.ico") self.image2 = QImage("pyqt5/images/cartoon1.ico") self.image3 = QImage("pyqt5/images/cartoon1.ico") self.width = 600 self.height = 300 self.resize(self.width, self.height) self.label1.installEventFilter(self) self.label2.installEventFilter(self) self.label3.installEventFilter(self) mainLayout = QGridLayout(self) mainLayout.addWidget(self.label1, 500, 0) mainLayout.addWidget(self.label2, 500, 1) mainLayout.addWidget(self.label3, 500, 2) mainLayout.addWidget(self.LabelState, 600, 1) self.setLayout(mainLayout) def eventFilter(self, watched, event): # print(type(watched)) if watched == self.label1: # 只對(duì)label1的點(diǎn)擊事件進(jìn)行過濾,重寫其行為,其它事件會(huì)被忽略 if event.type() == QEvent.MouseButtonPress: # 這里對(duì)鼠標(biāo)按下事件進(jìn)行過濾,重寫其行為 mouseEvent = QMouseEvent(event) if mouseEvent.buttons() == Qt.LeftButton: self.LabelState.setText("按下鼠標(biāo)左鍵") elif mouseEvent.buttons() == Qt.MidButton: self.LabelState.setText("按下鼠標(biāo)中鍵") elif mouseEvent.buttons() == Qt.RightButton: self.LabelState.setText("按下鼠標(biāo)右鍵") '''轉(zhuǎn)換圖片大小''' transform = QTransform() transform.scale(0.5, 0.5) tmp = self.image1.transformed(transform) self.label1.setPixmap(QPixmap.fromImage(tmp)) if event.type() == QEvent.MouseButtonRelease: # 這里對(duì)鼠標(biāo)釋放事件進(jìn)行過濾,重寫其行為 self.LabelState.setText("釋放鼠標(biāo)按鍵") self.label1.setPixmap(QPixmap.fromImage(self.image1)) return QDialog.eventFilter(self, watched, event) # 對(duì)于其它情況,會(huì)返回系統(tǒng)默認(rèn)的事件處理方法 if __name__ == "__main__": app = QApplication(sys.argv) win = EventFilter() win.show() app.exec_()
到此這篇關(guān)于PyQt5 事件處理機(jī)制的文章就介紹到這了,更多相關(guān)PyQt5 事件處理內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
- python GUI庫圖形界面開發(fā)之PyQt5信號(hào)與槽事件處理機(jī)制詳細(xì)介紹與實(shí)例解析
- python編程PyQt5創(chuàng)建按鈕及觸發(fā)點(diǎn)擊事件示例解析
- 使用pyqt5 實(shí)現(xiàn)ComboBox的鼠標(biāo)點(diǎn)擊觸發(fā)事件
- PyQt5 closeEvent關(guān)閉事件退出提示框原理解析
- PyQt5重寫QComboBox的鼠標(biāo)點(diǎn)擊事件方法
- pyqt5 comboBox獲得下標(biāo)、文本和事件選中函數(shù)的方法
- PyQt5每天必學(xué)之事件與信號(hào)
相關(guān)文章
python+Word2Vec實(shí)現(xiàn)中文聊天機(jī)器人的示例代碼
本文主要介紹了python+Word2Vec實(shí)現(xiàn)中文聊天機(jī)器人,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2023-03-03python數(shù)據(jù)寫入列表并導(dǎo)出折線圖
這篇文章主要介紹了python數(shù)據(jù)寫入列表并導(dǎo)出折線圖,文章以舉例展開對(duì)文章主題的介紹,具有一定的參考價(jià)值,需要的小伙伴可以參考一下2022-01-01Tensorflow實(shí)現(xiàn)酸奶銷量預(yù)測(cè)分析
這篇文章主要為大家詳細(xì)介紹了Tensorflow酸奶銷量預(yù)測(cè)分析,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2019-07-07Python過濾txt文件內(nèi)重復(fù)內(nèi)容的方法
今天小編就為大家分享一篇Python過濾txt文件內(nèi)重復(fù)內(nèi)容的方法,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過來看看吧2018-10-10python編程簡(jiǎn)單幾行代碼實(shí)現(xiàn)視頻轉(zhuǎn)換Gif示例
這篇文章主要為大家介紹了簡(jiǎn)單使用幾行python代碼就可以實(shí)現(xiàn)將視頻轉(zhuǎn)換Gif的示例過程,有需要的朋友可以借鑒參考下,希望能夠有所幫助2021-10-10