網站首頁 編程語言 正文
PyQt5 事件處理機制
PyQt為事件處理提供了兩種機制:高級的信號與槽機制,以及低級的事件處理機制。信號與槽可以說是對事件處理機制的高級封裝。
常見事件類型:
- 鍵盤事件:按鍵按下和松開。
- 鼠標事件:鼠標指針移動,鼠標按下和松開。
- 拖放事件:用鼠標進行拖放。
- 滾輪事件:鼠標滾輪滾動。
- 繪屏事件:重繪屏幕的某些部分。
- 定時事件:定時器到時。
- 焦點事件:鍵盤焦點移動。
- 進入/離開事件:鼠標指針移入Widget內,或者移出。
- 移動事件:Widget的位置改變。
- 大小改變事件:Widget的大小改變。
- 顯示/隱藏事件:Widget顯示和隱藏。
- 窗口事件:窗口是否為當前窗口。
PyQt提供了如下5種事件處理和過濾方法(有弱到強):
- 重新實現事件函數,比如mousePressEvent(),keyPressEvent()等等。
- 重新實現QObject.event()。
- 安裝時間過濾器。
- 在QApplication中安裝事件過濾器。
- 重新實現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 = "請點擊這里觸發追蹤鼠標功能"
self.update() # 重繪事件,也就是除非paintEvent函數
# 重新實現關閉事件
def closeEvent(self, event):
print("Closed")
# 重新實現上下文菜單事件
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()
'''重新實現繪制事件'''
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)
# 清空文本信息槽函數
def clearMessage(self):
self.message = ""
# 重新實現調整窗口大小事件
def resizeEvent(self, event):
self.text = "調整窗口大小為: QSize({0}, {1})".format(event.size().width(), event.size().height())
self.update()
# 重新實現鼠標釋放事件
def mouseReleaseEvent(self, event) -> None:
if self.justDoubleClikcked:
self.justDoubleClikcked = False
else :
self.setMouseTracking(not self.hasMouseTracking()) # 單擊鼠標
if self.hasMouseTracking():
self.text = "你釋放了鼠標 開啟鼠標跟蹤功能.\n\n" + \
"請移動鼠標\n\n" + \
"單擊鼠標可以關閉這個功能"
else:
self.text = "你釋放了鼠標 關閉鼠標跟蹤功能" + \
"單擊鼠標可以開啟這個功能"
self.update()
'''重新實現鼠標移動事件'''
def mouseMoveEvent(self, event):
if not self.justDoubleClikcked:
globalPos = self.mapToGlobal(event.pos())# 將窗口坐標轉換為屏幕坐標
self.text = """鼠標位置:
窗口坐標為:QPoint({0}, {1})
屏幕坐標為:QPoint({2}, {3})""".format(event.pos().x(), event.pos().y(), globalPos.x(), globalPos.y())
self.update()
'''重新實現鼠標雙擊事件'''
def mouseDoubleClickEvent(self, event):
self.justDoubleClikcked = True
self.text = "你雙擊了鼠標"
self.update()
def mousePressEvent(self, event):
self.text = "你按下了鼠標"
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()
'''重新實現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表示本次事件已經執行處理
else:
return QWidget.event(self, event) # 繼續處理事件
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("請點擊")
self.label2 = QLabel("請點擊")
self.label3 = QLabel("請點擊")
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: # 只對label1的點擊事件進行過濾,重寫其行為,其它事件會被忽略
if event.type() == QEvent.MouseButtonPress: # 這里對鼠標按下事件進行過濾,重寫其行為
mouseEvent = QMouseEvent(event)
if mouseEvent.buttons() == Qt.LeftButton:
self.LabelState.setText("按下鼠標左鍵")
elif mouseEvent.buttons() == Qt.MidButton:
self.LabelState.setText("按下鼠標中鍵")
elif mouseEvent.buttons() == Qt.RightButton:
self.LabelState.setText("按下鼠標右鍵")
'''轉換圖片大小'''
transform = QTransform()
transform.scale(0.5, 0.5)
tmp = self.image1.transformed(transform)
self.label1.setPixmap(QPixmap.fromImage(tmp))
if event.type() == QEvent.MouseButtonRelease: # 這里對鼠標釋放事件進行過濾,重寫其行為
self.LabelState.setText("釋放鼠標按鍵")
self.label1.setPixmap(QPixmap.fromImage(self.image1))
return QDialog.eventFilter(self, watched, event) # 對于其它情況,會返回系統默認的事件處理方法
if __name__ == "__main__":
app = QApplication(sys.argv)
win = EventFilter()
win.show()
app.exec_()
原文鏈接:https://blog.csdn.net/songyulong8888/article/details/128104547
相關推薦
- 2022-11-06 python分析inkscape路徑數據方案簡單介紹_python
- 2022-11-27 Docker?容器互聯互通的實現方法_docker
- 2022-12-05 C#?md5?算法實現代碼_C#教程
- 2023-07-25 MyBatis數據操作和動態SQL
- 2022-03-23 C++成員初始化列表_C 語言
- 2022-08-04 docker安裝elastic?search的詳細過程_docker
- 2022-12-21 C++強制轉換與智能指針示例詳解_C 語言
- 2023-01-20 解決Building?wheel?for?wrapt?(setup.py)?...?error的問題
- 最近更新
-
- window11 系統安裝 yarn
- 超詳細win安裝深度學習環境2025年最新版(
- Linux 中運行的top命令 怎么退出?
- MySQL 中decimal 的用法? 存儲小
- get 、set 、toString 方法的使
- @Resource和 @Autowired注解
- Java基礎操作-- 運算符,流程控制 Flo
- 1. Int 和Integer 的區別,Jav
- spring @retryable不生效的一種
- Spring Security之認證信息的處理
- Spring Security之認證過濾器
- Spring Security概述快速入門
- Spring Security之配置體系
- 【SpringBoot】SpringCache
- Spring Security之基于方法配置權
- redisson分布式鎖中waittime的設
- maven:解決release錯誤:Artif
- restTemplate使用總結
- Spring Security之安全異常處理
- MybatisPlus優雅實現加密?
- Spring ioc容器與Bean的生命周期。
- 【探索SpringCloud】服務發現-Nac
- Spring Security之基于HttpR
- Redis 底層數據結構-簡單動態字符串(SD
- arthas操作spring被代理目標對象命令
- Spring中的單例模式應用詳解
- 聊聊消息隊列,發送消息的4種方式
- bootspring第三方資源配置管理
- GIT同步修改后的遠程分支