Widget -> event
基于窗体的应用程序都是由事件驱动的,列如:鼠标事件(鼠标的单击双击)、键盘事件(按键的按下释放)、窗体绘制事件(某个事件的重绘)等,产生的事件进入一个事件队列,由应用程序的事件循环进行处理。
在PyQt5中,事件是一种对象,由抽象类QEvent表示,开头引入库
from PyQt5.QtCore import QEvent
QEvent有很多子类,表示具体的事件,列如
QMouseEvent,QKeyEvent,QPaintEvent,QCloseEvent,QResizeEvent,etc.
event(self, event)
参数event是QEvent类型。QEvent类有主要以下三个接口:
# 枚举类型 event.type()的每一个值都对应于一个事件类,这里,event.type()对应的事件类是 QKeyEvent
# 具体的事件类型为键盘的释放 QEvent.KeyRelease
event.type() == QEvent.KeyRelease
默认函数名称 | 触发时机 | 参数event类型 |
---|---|---|
mousePressEvent(self, event) | 鼠标按键按下时触发 | QMouseEvent |
mouseReleaseEvent(self, event) | 鼠标按键释放时触发 | QMouseEvent |
mouseMoveEvent(self, event) | 鼠标按键移动时触发 | QMouseEvent |
mouseDoubleClickEvent(self, event) | 鼠标按键双击时触发 | QMouseEvent |
keyPressEvent(self, event) | 键盘按键按下时触发 | QKeyEvent |
keyReleaseEvent(self, event) | 键盘按键释放时触发 | QKeyEvent |
paintEvent(self, event) | 在界面需要重新绘制时触发 | QPaintEvent |
closeEvent(self, event) | 一个窗体关闭时触发 | QCloseEvent |
resizeEvent(self, event) | 组件改变大小时触发 | QResizeEvent |
ui_1009.py
# -*- coding: utf-8 -*-
# Form implementation generated from reading ui file 'ui_1009.ui'
#
# Created by: PyQt5 UI code generator 5.15.4
#
# WARNING: Any manual changes made to this file will be lost when pyuic5 is
# run again. Do not edit this file unless you know what you are doing.
from PyQt5 import QtCore, QtGui, QtWidgets
class Ui_Widget(object):
def setupUi(self, Widget):
Widget.setObjectName("Widget")
Widget.resize(400, 300)
self.label = QtWidgets.QLabel(Widget)
self.label.setGeometry(QtCore.QRect(130, 265, 241, 21))
self.label.setObjectName("label")
self.pushButton = QtWidgets.QPushButton(Widget)
self.pushButton.setGeometry(QtCore.QRect(104, 130, 161, 23))
self.pushButton.setObjectName("pushButton")
self.pushButton_2 = QtWidgets.QPushButton(Widget)
self.pushButton_2.setGeometry(QtCore.QRect(110, 180, 151, 23))
self.pushButton_2.setObjectName("pushButton_2")
self.retranslateUi(Widget)
QtCore.QMetaObject.connectSlotsByName(Widget)
def retranslateUi(self, Widget):
_translate = QtCore.QCoreApplication.translate
Widget.setWindowTitle(_translate("Widget", "窗体"))
self.label.setText(_translate("Widget", "鼠标的当前坐标位置是:"))
self.pushButton.setText(_translate("Widget", "Button_resizeEvent"))
self.pushButton_2.setText(_translate("Widget", "Button_moveEvent"))
ui_1009_main.py
# -*- coding: utf-8 -*-
# @Time : 2022/10/9 11:16
# -*- coding: utf-8 -*-
# @Time : 2022/10/9 11:16
import sys
from PyQt5.QtWidgets import QWidget, QApplication, QMessageBox
from PyQt5.QtCore import QEvent, Qt, pyqtSlot
from PyQt5.QtGui import QPixmap, QPainter
from ui_1009 import Ui_Widget
class QmyWidget(QWidget):
def __init__(self, parent=None):
super().__init__(parent)
self.ui = Ui_Widget()
self.ui.setupUi(self)
# 典型事件的默认处理函数
# 组件改变大小事件
def resizeEvent(self, event):
H = self.height()
W = self.width()
Hbtn = self.ui.pushButton.height()
Wbtn = self.ui.pushButton.width()
# self.ui.pushButton.setGeometry((H-Hbtn)/2 , (W-Wbtn)/2, Hbtn, Wbtn)
# 从屏幕上((W - Wbtn) / 2, (H - Hbtn) / 2)位置开始(即为最左上角的点),显示一个Wbtn*Hbtn的界面(宽Wbtn,高Hbtn)
self.ui.pushButton.setGeometry((W - Wbtn) / 2, (H - Hbtn) / 2, Wbtn, Hbtn)
def mousePressEvent(self, event):
pt = event.pos() # 鼠标的位置
if (event.button() == Qt.LeftButton): # button()函数:返回值是枚举类型Qt.MouseButton, 表示哪个按键(Qt.LeftButton、Qt.RightButton等)被按下
self.ui.label.setText("鼠标的当前坐标位置是:(%d,%d)"% (pt.x(),pt.y()))
super().mousePressEvent(event)
# 自定义键盘按键按下触发事件
def keyPressEvent(self, event):
# def keyReleaseEvent(self, event):
rect = self.ui.pushButton_2.geometry()
if event.key() in set ([Qt.Key_4, Qt.Key_Left]):
# setGeometry():从屏幕上(rect.left()-20, rect.top())位置开始(即为最左上角的点),显示一个rect.width()*rect.height()的界面(宽rect.width(),高rect.height())
self.ui.pushButton_2.setGeometry(rect.left()-50, rect.top(), rect.width(), rect.height()) # rect.left()-50 每按下左键一次左移50个像素,使左移加速
elif event.key() in set ([Qt.Key_6, Qt.Key_Right]):
self.ui.pushButton_2.setGeometry(rect.left() + 2, rect.top(), rect.width(), rect.height())
elif event.key() in set ([Qt.Key_8, Qt.Key_Up]):
self.ui.pushButton_2.setGeometry(rect.left(), rect.top() - 2, rect.width(), rect.height())
elif event.key() in set ([Qt.Key_2, Qt.Key_Down]):
self.ui.pushButton_2.setGeometry(rect.left(), rect.top() + 2, rect.width(), rect.height())
# 重绘触发事件
def paintEvent(self, event):
painter = QPainter(self)
img = QPixmap("./images/img-background.png")
painter.drawPixmap(0, 0, self.width(), self.height(), img)
super().paintEvent(event)
# 窗体关闭事件
def closeEvent(self, event):
dlgTitle = "消息对话框"
strText = "确定要退出么?"
defaultButton = QMessageBox.NoButton
result = QMessageBox.question(self, dlgTitle, strText, QMessageBox.Yes | QMessageBox.No, defaultButton)
if (result == QMessageBox.Yes) :
event.accept()
else:
event.ignore()
if __name__ == "__main__":
app = QApplication(sys.argv)
btnevent = QmyWidget()
btnevent.show()
sys.exit(app.exec_())
# event函数事件屏蔽/预处理
def event(self, event):
if (event.type() == QEvent.Paint):
return True # 不在绘制背景
elif (event.type() == QEvent.KeyRelease) and (event.key() == Qt.Key_Tab):
rect = self.ui.pushButton.geometry()
self.ui.pushButton.setGeometry(rect.left() + 50, rect.top(), rect.width(), rect.height())
return super().event(event)
第一个判断:判断的事件类型为 QEvent.Paint,直接返回True,退出函数 。
QEvent.Paint事件类型的默认处理函数是 paintEvent(self, event),用于绘制窗体背景图片。执行该句后,将不会对重新实现的 paintEvent(self, event) 函数做处理,也就不会绘制窗体的背景图片。
第二个判断:判断的事件类型为QEvent.KeyRelease,并且按键是Tab键,按钮右移50个像素,右移加速