当前位置:   article > 正文

PyQt5默认事件处理_pyqt5 重写最小化事件

pyqt5 重写最小化事件

一、引言
基于窗体(Widget)的应用程序都是由事件(event)驱动的,鼠标单击、按下某个按键、重绘某个组件、最小化窗口都会产生相应的事件,应用程序对这些事件作出相应的响应处理以实现程序的功能。

二、应用程序的事件循环
事件主要由操作系统的窗口系统产生的,产生的事件进入一个事件队列,由应用程序的事件循环进行处理。以下是PyQt5应用程序的主程序结构:

app = QApplication(sys.argv)
mainform = QmyWidget()
mainform.show()
sys.exit(app.exec_())
  • 1
  • 2
  • 3
  • 4

app是创建的应用程序对象,最后执行的app.exec_()开启了应用程序的事件处理循环。应用程序会对事件队列中排队的事件进行处理,还可以对相同事件进行合并处理。例如一个界面组件的重绘事件paintEvent,如果在事件队列中重复出现同一事件,应用程序就会合并处理,所以,事件处理是一种异步处理机制

三、事件类型及默认的事件处理函数
在PyQt5中,事件是一种对象,由抽象类QEvent表示。QEvent还有很多子类表示具体的事件,如QKeyEvent表示按键事件,QMouseEvent表示鼠标事件,QPaintEvent表示窗体绘制事件。

当一个事件发生时,PyQt5会根据事件的具体类型用QEvent相应的子类创建一个事件实例对象,然后传递给产生事件的对象的event()函数进行处理。

QObject类及其子类都可以进行事件的处理,但主要还是窗体类(QWidget及其子类)中用到事件处理。以下是QObject类的event()函数的原型:

event(self, <em>e</em>)
  • 1

参数e是QEvent类型,QEvent类主要有以下3个接口函数:
(1)accept():表示事件接收者接受此事件,对此事件进行处理,接受的事件不会再传播给上层容器组件。
(2)ignore():表示事件接收者忽略次事件,忽略的事件将传播给上层容器组件。
(3)type():返回事件的类型,是枚举类型QEvent.Type,这个枚举类型由100多个值,表示100多个类型的事件。

枚举类型QEvent.Type的每个值都对应于一个事件类,例如QEvent.KeyPress类型表示的是按键事件,对应的事件类是QKeyEvent。

一个类接收到事件后,首先会触发其event()函数,如果event()函数不做任何处理,就会自动触发默认的事件处理函数。

QWidget类是所有界面组件类的父类,它定义了各种事件的默认处理函数,例如鼠标双击事件的枚举类型是QEvent.MouseButtonDblClick,默认的事件处理函数是mouseDoubleClickEvent(),其函数原型是:

mouseDoubleClickEvent(self, event)
  • 1

参数event是QMouseEvent类型,这是鼠标类型对应的类。
QWidget定义了很多的默认事件处理函数,都会传递一个event参数,但是event的类型由具体事件类型决定。常用的默认事件处理函数如表所示(表中只列出了函数名称,未列出函数输入参数)

默认函数名称触发时机参数event类型
mousePressEvent()鼠标按键按下时触发QMouseEvent
mouseReleaseEvent()鼠标按键释放时触发QMouseEvent
mouseMoveEvent()鼠标移动时触发QMouseEvent
mouseDoubleClickEvent()鼠标双击时触发QMouseEvent
keyPressEvent()键盘按键按下时触发QKeyEvent
keyReleaseEvent()键盘按键释放时触发QKeyEvent
paintEvent()在界面需要重新绘制时触发QPaintEvent
closeEvent()一个窗体关闭时触发QCloseEvent
showEvent()一个窗体显示时触发QShowEvent
hideEvent()一个窗体隐藏时触发QHideEvent
resizeEvent()组件改变大小时触发,如一个窗口改变大小时QResizeEvent
focusInEvent()当一个组件获得键盘焦点时触发,如一个QLineEdit组件获得输入焦点QFocusEvent
focusOutEvent()当一个组件失去键盘焦点时触发,如一个QLineEdit组件失去输入焦点QFocusEvent
enterEvent()当鼠标进入组件的屏幕空间时触发,如鼠标移动到一个QPushButton组件上QEvent
leaveEvent()当鼠标离开组件的屏幕空间时触发,如鼠标离开一个QPushButton组件QEvent
dragEnterEvent()拖动操作正在进行,鼠标移动到组件上方时触发QDragEnterEvent
dragLeaveEvent()拖动操作正在进行,鼠标移出组件上方时触发QDragLeaveEvent
dragMoveEvent()拖动操作正在进行,鼠标移动时触发QDragMoveEvent
dropEvent()当拖动操作在某个组件上放下时触发QDropEvent

用户在继承于QWidget或其子类的自定义类中可以重新实现这些默认的事件处理函数,从而实现一些需要的功能。例如,QWidget没有clicked()信号,那么就不能通过信号与槽的方式实现对鼠标单击的处理,但是可以重新实现mouseReleaseEvent()函数对鼠标单击事件进行处理。

下列例子对基于项目模板widgetApp的默认事件处理作说明:
在这里插入图片描述

import sys
from PyQt5.QtWidgets import QApplication, QWidget, QMessageBox
from PyQt5.QtCore import pyqtSlot, Qt, QEvent
from PyQt5.QtGui import QPainter, QPixmap

from ui_Widget import Ui_Widget
class QmyWidgrt(QWidget):
	def __init__(self, parent = None):
		super().__init__(parent)	#调用父类构造函数,创建窗体
		self.ui = Ui_Widget()		#创建UI对象
		self.ui.SetupUi(self)		#构造UI
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11

然后在QmyWidget类中重新实现了以下一些典型事件的默认处理函数。
(1)paintEvent()
在界面需要重新绘制时触发,在此事件函数里可以实现一些自定义的绘制功能。绘制窗体背景图片:

def paintEvent(self, event):
	painter = QPainter(self)
	pic = QPixmap("sea1.jpg")
	painter.drawPixmap(0, 0, self.width(), self.height(), pic)
	super().paintEvent(event)
  • 1
  • 2
  • 3
  • 4
  • 5

函数的功能是将一个图片文件sea1.jpg绘制到窗体的整个区域,绘图时使用了窗体的画笔对象painter。图片文件sea1.jpg必须与使用其的脚本文件在同一个目录里。最后一行语句表示再执行父类的paintEvent()事件处理函数,以便父类执行其内建的一些操作。

(2)resizeEvent()
在窗体改变大小时触发,在此事件函数里,根据窗体大小,使一个按钮btnTest总是居于窗体的中央。

def resizeEvent(self, event):
	W = self.width()
	H = self.height()
	Wbtn = self.ui.btnTest.width()
	Hbtn = self.ui.btnTest.height()
	self.ui.btnTest.setGeometry((W-Wbtn)/2, (H-Hbtn)/2, Wbtn, Hbtn)
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6

(3)closeEvent()
在窗体关闭时触发,在此事件函数里可以使用一个对话框询问是否关闭窗体,代码如下:

def closeEvent(self, event):
	dlgTitle = "Question消息框"
	strInfo = "closeEvent事件触发,确定要退出吗?"
	defaultBtn = QMessageBox.NoButton
	result = QMessageBox.question(self, dlgTitle, strInfo, QMessageBox.Yes | QMessageBox.No, defaultBtn)
	if(result == QMessageBox.Yes):
		event.accept()			#窗体可关闭
	else:
		event.ignore()			#窗体不可关闭
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9

使用了对话框QMessageBox询问是否关闭窗体。
在这里插入图片描述
closeEvent(event)函数的参数event是QCloseEvent类型,根据对话框的返回结果调用QCloseEvent的accept()函数可以关闭窗体,ignore()函数则不关闭窗体。

(4)mousePressEvent()
在鼠标按键按下时触发,在此事件函数里判断鼠标左键是否按下,如果是左键按下就显示鼠标光标处的屏幕坐标,即:

def mousePressEvent(self, event):
	pt = event.pos()		#鼠标位置,QPoint
	if(event.button() == Qt.LeftButton):	#鼠标左键按下
		self.ui.LabMove.setText("(x, y) = (%d, %d)" %(pt.x(), pt.y()))
		rect = self.ui.LabMove.geometry()
		self.ui.LabMove.setGeometry(pt.x(), pt.y(), rect.width(), rect.height())
	super().mousePressEvent(event)
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7

参数event是QMouseEvent类型,QMouseEvent有以下几个接口函数,表示按下的按键的信息和鼠标坐标信息。

  • button()函数:返回值是枚举类型Qt.MouseButton,表示被按下的是鼠标的哪个按键,有Qt.NoButton、Qt.LeftButton、Qt.RightButton和Qt.MidButton等多种取值。
  • buttons()函数:返回值是枚举类型Qt.MouseButton的取值组合,可用于判断多个按键被按下的情况,例如判断鼠标左键和右键同时按下时的语句是:
if(event.buttons() & Qt.LeftButton) and (event.buttons() & Qt.RightButton):
  • 1
  • x()函数和y()函数:返回值是int类型;pos()函数,返回值是QPoint类型。这两组函数的返回值都表示鼠标光标在接收此事件的组件(widget)上的相对坐标。
  • localPos()函数:返回值是QPointF类型,表示鼠标光标在接收此事件的组件(widget)或项(item)上的相对坐标。
  • windowPos()函数:返回值是QPointF类型,表示鼠标光标在接收此事件的窗口(window)上的相对坐标。
  • globalX()函数和globalY()函数:返回值是int类型;globalPos()函数,返回值是QPoint类型。这两组函数的返回值都表示鼠标光标的全局坐标,也就是屏幕上的坐标。
  • screenPos()函数:返回值是QPointF类型,表示鼠标光标在接收此事件的屏幕(screen)上的全局坐标。

(5)keyPressEvent()或keyReleaseEvent()
keyPressEvent()在键盘上的按键按下时触发,keyReleaseEvent()在按键释放时触发,为keyPressEvent()编写的代码如下:

def keyPressEvent(self, event):
	rect = self.ui.btnMove.geometry()
	if event.key() in set([Qt.Key_A, Qt.Key_Left]):
		self.ui.btnMove.setGeometry(rect.left() - 20, rect.top(), rect.width(), rect.height())
	elif event.key() in set([Qt.Key_D, Qt.Key_Right]):
		self.ui.btnMove.setGeometry(rect.left() + 20, rect.top(), rect.width(), rect.height())
	elif event.key() in set([Qt.Key_W, Qt.Key_Up]):
		self.ui.btnMove.setGeometry(rect.left, rect.top() - 20, rect.width(), rect.height())
	elif event.key() in set([Qt.Key_S, Qt.Key_Down]):
		self.ui.btnMove.setGeometry(rect.left, rect.top() + 20, rect.width(), rect.height())
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10

keyPressEvent(event)函数的参数event是QKeyEvent类型,它有以下两个主要的接口函数,表示按下的按键的信息。

  • key()函数:返回值类型是int,表示被按下的按键,与枚举类型Qt.Key的取值对应。枚举类型Qt.Key包括键盘上所有按键的枚举值,如Qt.Key_Escape、Qt.Key_Tab、Qt.Key_Delete、Qt.Key_Alt、Qt.Key_F1、Qt.Key_A等(详见Qt帮助文档)。
  • modifiers()函数:返回值是枚举类型Qt.KeyboardModifier的取值组合,表示一些用于组合的按键,如Ctrl、Alt、Shift等按键。例如,判断Ctrl+Q是否被按下的语句如下:
if(event.key() == Qt.Key_Q) and (event.modifiers() & Qt.ControlModifier):
  • 1

这段程序是期望在按下W、A、S、D或上、下、左、右方向键时,窗体上的按钮btnMove能上下左右移动位置。但是却会发现在使用keyPressEvent()事件函数时,只有W、A、S、D有效,而如果使用的是keyReleaseEvent()函数,则W、A、S、D和上、下、左、右方向键都有效。这说明上、下、左、右方向键按下时不会产生QEvent.KeyPress类型的事件。

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/你好赵伟/article/detail/838961
推荐阅读
相关标签
  

闽ICP备14008679号