窗口和控件的常用事件
窗口和控件的常用事件包括窗口或控件的隐藏、显示、移动、缩放、重绘、关闭、获得和失去焦点等,通常需要重写这些事件的处理函数,以便达到特定的目的。
显示事件QShowEvent和隐藏事件QHideEvent
在用show()方法或 setVisible(True)方法显示一个顶层窗口之前会发生 QEvent.Show事件调用showEvent(QShowEvent)处理函数,显示事件类 QShowEvent 只有从QEvent 继承的属性没有自已特有的属性。
在用hide()方法或 setVisible(False)方法隐藏一个顶层窗口之前会发生 QEvent.Hide 事件调用hideEvent(QHideEvent)处理函数,隐藏事件类QHideEvent 只有从 QEvent 继承的属性,没有自已特有的属性。利用显示和隐藏事件的处理函数,可以在窗口显示之前或被隐藏之前做一些预处理工作。
缩放事件QResizeEvent和移动事件QMoveEvent
当一个窗口或控件的宽度和高度发生改变时会触发 QEvent.Resize 事件,调用resizeEvent(QResizeEvent)处理函数。
缩放事件类QResizeEvent 只有两个方法oldSize()和 size(),分别返回缩放前和缩放后的窗口尺寸QSize
当改变一个窗口或控件的位置时会触发 QEvent,Move 事件,调用moveEvent(QMoveEvent)处理函数。
移动事件类QMoveEvent 只有两个方法oldPos()和 pos(),分别返回窗口左上角移动前和移动后的位置 QPoint。
绘制事件QPaintEvent
绘制事件QPaintEvent是窗体系统产生的在一个窗口首次显示隐藏后又显示缩放窗口移动控件,以及调用窗口的 update()repaint()resize()方法时都会发 QEvent.Paint事件。
绘制事件发生时,会调用paintEvent(QPaintEvent)处理函数该函数是受保护的,不能直接用代码调用,通常在 paintEvent(QPaintEvent)处理函数中处理一些与绘图显示有关的事情。
绘制事件类QPaintEvent 只有两个方法 rect()和 region()方法分别返回被重绘的矩形区域 QRect 和裁剪区域 QRegion。
进人事件和离开事件 QEnterEvent
当光标进入窗口时,会触发 QEvent,Enter 进人事件,进人事件的处理函数是enterEvent(QEnterEvent),QEnterEvent 的方法如表所示;
QEnterEvent的方法 | 返回值的类型 | QEnterEvent的方法 | 返回值的类型 |
---|---|---|---|
clone() | QEnterEvent | pos() | QPoint |
globalPos() | QPoint | screenPos() | QPointF |
globalX() | int | windowPos() | QPointF |
globalY() | int | x() | int |
localPos() | QPointF | y() | int |
当光标离开窗口时,会触发QEvent,Leave 离开事件离开事件的处理函数是 leaveEvent(QEvent)。可以重写这两个函数,以达到特定的目的。
焦点事件 QFocusEvent
一个控件获得键盘焦点时,可以接受键盘的输人。控件获得键盘焦点的方法很多,例如按 Tab 键、鼠标、快捷键等。
- 当一个控件获得和失去键盘输人焦点时,会触发 QEvent.FocusIn 和QEvent.FocusOut 事件,这两个事件的处理函数分别是 focusInEvent(QFocusEvent)和 focusOutEvent(QFocusEvent)
- 焦点事件类QFocusEvent 的方法有getFocus()_lostFocus()和 reason()。
- 事件类型 type()
- 当事件类型 type()的值是 QEvent.FocusIn 时getFocus()方法的返回值是 True,
- 当事件类型type()的值是QEvent.FocusOut 时lostFocus()方法的返回值是 True;
- reason()方法返回获得焦点的原因其返回值的类型是Qt.FocusReason,其值 有:
- Qt.MouseFocusReason
- Qt.TabFocusReason
- Qt.BacktabFocusReason
- Qt.ActiveWindowFocusReason
- Qt.PopupFocusReason
- Qt.ShortcutFocusReason
- Qt.MenuBarFocusReason
- Qt.OtherFocusReason
关闭事件QCloseEvent
当用户单击窗口右上角的X按钮或执行窗口的 close()方法时,会触发 QEvent,Close事件,调用closeEvent(QCloseEvent)处理该事件。
如果事件用ignore()方法忽略了,则什么也不会发生;
如果事件用accept()方法接收了,首先窗口被隐藏,在窗口设置了setAttribute(Qt.WA_DeleteOnClose,True)属性的情况下,窗口会被删除。
窗口事件类QCloseEvent 没有特殊的属性,只有从 QEvent 继承来的方法。
定时器事件QTimerEvent
从QObject 类继承的窗口和控件都会有startTimer(int,timerType =Qt.CoarseTimer)方法和 killTimer(int)方法。
startTimer()方法会启动一个定时器,并返回定时器的 ID 号。
- 如果不能启动定时器,则返回值是 0,参数 int 是定时器的事件间隔,单位是毫秒
- timerType 是定时器的类型,可以取
- Qt.PreciseTimer
- Qt.CoarseTimer
- Qt.VeryCoarseTimer。
- 窗口或控件可以用startTimer()方法启动多个定时器,启动定时器后,会触发 timerEvent(QTimerEvent)事件,QTimerEvent是定时器事件类。
- 用QTimerEvent的 timerId()方法可以获取触发定时器事件的定时器ID;
- 用killTimer(int)方法可以停止定时器,参数是定时器的 ID。
下面的程序启动窗口上的两个定时器,这两个定时器的时间间隔不同,用定时器事件识别是哪个定时器触发了定时器事件,可用按钮停止定时器。
# -*- coding: UTF-8 -*-
# File date: Hi_2023/3/1 20:29
# File_name: demo.py
from PySide6.QtWidgets import QApplication,QWidget,QPushButton,QHBoxLayout
from PySide6.QtCore import Qt
import sys
class MyWidget(QWidget):
def __init__(self,parent=None):
super().__init__(parent)
self.ID_1 = self.startTimer(500,Qt.TimerType.PreciseTimer)# 创建第 1个定时器
self.ID_2 = self.startTimer(1000,Qt.TimerType.CoarseTimer)# 创建第2个定时器
btn_1 = QPushButton("停止第1个定时器",self)
btn_2 = QPushButton("停止第2个定时器",self)
btn_1.clicked.connect(self.killTimer_1)
btn_2.clicked.connect(self.killTimer_2)
h = QHBoxLayout(self)
h.addWidget(btn_1)
h.addWidget(btn_2)
def timerEvent(self,event): # 定时器事件
print("我是第"+ str(event.timerId())+"个定时器")
def killTimer_1(self):
if self.ID_1:
self.killTimer(self.ID_1)# 停止第1个定时器
print(f"{'='* 20}第1个定时器停止{'='* 20}")
def killTimer_2(self):
if self.ID_2:
self.killTimer(self.ID_2)# 停止第2个定时器
print(f"{'='* 20}第2个定时器停止{'='* 20}")
if __name__ == '__main__':
app = QApplication(sys.argv)
win = MyWidget()
win.show()
sys.exit(app.exec())