PyQt5之事件处理

文章目录

  • 事件处理
  • 一、事件类型
  • 二、event()函数原型
  • 三、常见的默认事件处理函数
    • 代码示例
    • 运行结果
  • 四、使用event()函数屏蔽窗体事件
    • 代码示例
    • 运行结果


事件处理

Widget -> event

基于窗体的应用程序都是由事件驱动的,列如:鼠标事件(鼠标的单击双击)、键盘事件(按键的按下释放)、窗体绘制事件(某个事件的重绘)等,产生的事件进入一个事件队列,由应用程序的事件循环进行处理。


一、事件类型

在PyQt5中,事件是一种对象,由抽象类QEvent表示,开头引入库

from PyQt5.QtCore import QEvent

QEvent有很多子类,表示具体的事件,列如

QMouseEvent,QKeyEvent,QPaintEvent,QCloseEvent,QResizeEvent,etc.

二、event()函数原型

event(self, event)

参数event是QEvent类型。QEvent类有主要以下三个接口:

  • accept(),表示事件接收者接受此事件并进行处理
  • ignore(),表示事件接收者忽略此事件,忽略的事件将传播给上层容器组件
  • type(),返回事件的类型,可以枚举100多个值,也就是100多个类型的事件
# 枚举类型 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_())
    

运行结果

PyQt5之事件处理_第1张图片

四、使用event()函数屏蔽窗体事件

代码示例

    # 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个像素,右移加速

运行结果

PyQt5之事件处理_第2张图片


你可能感兴趣的:(PyQt5,GUI设计,qt,ui,python)