PyQt5之事件处理


事件处理

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_())
    

运行结果

3.gif

四、使用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个像素,右移加速

运行结果

event_btnMove


  • 2
    点赞
  • 13
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值