🌟想系统化学习 GUI 编程?看看这个:[Python GUI 编程] PySide & PyQt - 学习手册-CSDN博客

上图是 QWidget 支持的常见消息方法(不全但够用了,读者可以自行去进行父类追踪以获得更全的事件),本章只讲解各个消息的触发条件,不讲解消息触发时传入的消息对象的具体属性和函数(这个可以等用到时再去细查)。
小提示
上图中每个事件触发时都会传入对应事件的消息对象,对象是有自己的属性和方法的。通过传入的事件消息对象,我们可以得知事件触发时,触发该事件对象的具体信息。
0x01:QWidget 事件消息 — 显示和关闭事件

0x0101:showEvent(QShowEvent)
当控件显示时,会自动调用该控件的 showEvent() 方法,并传入一个 QShowEvent 对象:
import sys
from PyQt5.Qt import *
class MyWidget(QWidget):
def __init__(self):
super().__init__()
self.resize(800, 800)
def showEvent(self, QShowEvent):
"""
重写 showEvent 方法, 拦截事件信息
"""
print("窗口显示了, 我该干 ....")
# 1. 创建一个应用程序对象
app = QApplication(sys.argv)
# 2. 控件操作
window = MyWidget()
# 3. 展示控件
window.show()
# 4. 应用程序的执行,进入到消息循环
sys.exit(app.exec_())

0x0102:closeEvent(QCloseEvent)
当控件关闭时,会自动调用该控件的 closeEvent() 方法,并传入一个 QCloseEvent 对象:
import sys
from PyQt5.Qt import *
class MyWidget(QWidget):
def __init__(self):
super().__init__()
self.resize(800, 800)
def closeEvent(self, QCloseEvent):
"""
重写 closeEvent 方法, 拦截事件信息
"""
print("窗口关闭了, 我该干 ....")
# 1. 创建一个应用程序对象
app = QApplication(sys.argv)
# 2. 控件操作
window = MyWidget()
# 3. 展示控件
window.show()
# 4. 应用程序的执行,进入到消息循环
sys.exit(app.exec_())
上面代码运行,会显示一个窗口,当我们点击窗口的 X 键,即关闭按钮,就会触发 closeEvent() 方法,打印其中的内容。
0x02:QWidget 事件消息 — 窗口移动事件
当控件移动时,会自动调用该控件的 moveEvent() 方法,并传入一个 QMoveEvent 对象:
import sys
from PyQt5.Qt import *
class MyWidget(QWidget):
def __init__(self):
super().__init__()
self.resize(800, 800)
def moveEvent(self, QMoveEvent):
"""
重写 moveEvent 方法, 拦截事件信息
"""
print("窗口移动了, 我该干 ....")
# 1. 创建一个应用程序对象
app = QApplication(sys.argv)
# 2. 控件操作
window = MyWidget()
# 3. 展示控件
window.show()
# 4. 应用程序的执行,进入到消息循环
sys.exit(app.exec_())

0x03:QWidget 事件消息 — 窗口大小调整
当控件移动时,会自动调用该控件的 resizeEvent() 方法,并传入一个 QResizeEvent 对象:
import sys
from PyQt5.Qt import *
class MyWidget(QWidget):
def __init__(self):
super().__init__()
self.resize(800, 800)
def resizeEvent(self, QResizeEvent):
"""
重写 resizeEvent 方法, 拦截事件信息
"""
print("窗口大小改变了, 我该干....")
# 1. 创建一个应用程序对象
app = QApplication(sys.argv)
# 2. 控件操作
window = MyWidget()
# 3. 展示控件
window.show()
# 4. 应用程序的执行,进入到消息循环
sys.exit(app.exec_())

0x04:QWidget 事件消息 — 鼠标事件

直接上示例,运行后会显示一个窗口,读者自行到窗口点点,看看触发了哪个方法就行:
import sys
from PyQt5.Qt import *
class MyWidget(QWidget):
def __init__(self):
super().__init__()
self.resize(800, 800)
def enterEvent(self, QEvent):
print("鼠标进来啦")
def leaveEvent(self, QEvent):
print("鼠标离开啦")
def mousePressEvent(self, QMouseEvent):
print("鼠标按下啦")
def mouseReleaseEvent(self, QMouseEvent):
print("鼠标释放啦")
def mouseDoubleClickEvent(self, QMouseEvent):
print("鼠标双击啦")
def mouseMoveEvent(self, QMouseEvent):
"""
未设置 setMouseTracking(True) 时,只有鼠标按下时,鼠标移动才会触发事件
"""
print("鼠标移动啦")
# 1. 创建一个应用程序对象
app = QApplication(sys.argv)
# 2. 控件操作
window = MyWidget()
# 3. 展示控件
window.show()
# 4. 应用程序的执行,进入到消息循环
sys.exit(app.exec_())
0x0401:演示案例 — 无 Title 窗口的左键拖拽移动
在前面的学习中,我们想要移动一个窗口,就必须拖动窗口的标题,在后续的开发中,我们有可能会想去掉窗口的标题,那去了窗口的标题栏,我们要怎么移动窗口呢?Try 一下?下面是示例代码(目前还没有讲到如何去掉窗口上面的标题,所以就先不去了,先实现功能):
import sys
from PyQt5.Qt import *
class MyWidget(QWidget):
def __init__(self):
super().__init__()
self.resize(800, 800)
def mousePressEvent(self, event):
"""
在用户鼠标点击时,获取当前用户鼠标在窗口中的绝对位置和窗口在屏幕中的绝对位置
"""
if event.button() == Qt.LeftButton: # 判断用户是否按下鼠标左键
self.move_flag = True # 设置移动标志为 True
self.mouse_start_pos_x = event.globalPos().x() # 获取当前鼠标在窗口中的绝对位置 x 轴
self.mouse_start_pos_y = event.globalPos().y() # 获取当前鼠标在窗口中的绝对位置 y 轴
self.window_start_pos_x = self.x() # 获取窗口在屏幕中的绝对位置 x 轴
self.window_start_pos_y = self.y() # 获取窗口在屏幕中的绝对位置 y 轴
def mouseMoveEvent(self, event):
"""
在用户鼠标移动时会不断触发该事件,获取用户当前鼠标位置并对比初始位置,计算其相对位置
"""
if self.move_flag == True:
mouse_current_pos_x = event.globalPos().x() # 获取当前鼠标在窗口中的绝对位置 x轴
mouse_current_pos_y = event.globalPos().y() # 获取当前鼠标在窗口中的绝对位置 y轴
# 计算鼠标相对位置
mouse_move_x = (mouse_current_pos_x - self.mouse_start_pos_x)
mouse_move_y = (mouse_current_pos_y - self.mouse_start_pos_y)
window_move_x = self.window_start_pos_x + mouse_move_x
window_move_y = self.window_start_pos_y + mouse_move_y
# 移动窗口
self.move(window_move_x, window_move_y)
def mouseReleaseEvent(self, event):
"""
在用户鼠标释放时,删除初始位置
"""
if self.move_flag == True:
self.move_flag = False
del self.mouse_start_pos_x
del self.mouse_start_pos_y
del self.window_start_pos_x
del self.window_start_pos_y
# 1. 创建一个应用程序对象
app = QApplication(sys.argv)
# 2. 控件操作
window = MyWidget()
# 3. 展示控件
window.show()
# 4. 应用程序的执行,进入到消息循环
sys.exit(app.exec_())

0x05:QWidget 事件消息 — 键盘事件
直接上示例,运行后会显示一个窗口,读者随机敲击键盘按键,看看触发了哪个方法就行(前提是当前应用程序的窗口要获取焦点):
import sys
from PyQt5.Qt import *
class MyWidget(QWidget):
def __init__(self):
super().__init__()
self.resize(800, 800)
def keyPressEvent(self, QKeyEvent):
print("键盘上某一个按键被按下了")
def keyReleaseEvent(self, QKeyEvent):
print("键盘上某一个按键被释放了")
# 1. 创建一个应用程序对象
app = QApplication(sys.argv)
# 2. 控件操作
window = MyWidget()
# 3. 展示控件
window.show()
# 4. 应用程序的执行,进入到消息循环
sys.exit(app.exec_())
0x0501:演示案例 — 让指定控件获取键盘事件
不知道读者有没有想过一个事情,比如我又有两个控件,QLabel 控件在 QWidget 控件内部,我想让 QLabel 控件捕获键盘事件,我该怎么做?看下面这个示例(主要是 grabKeyboard() 方法,该方法能让指定控件捕获键盘事件):
import sys
from PyQt5.Qt import *
class MyWidget(QWidget):
def __init__(self):
super().__init__()
self.resize(800, 800)
def keyPressEvent(self, QKeyEvent):
print("zzz")
class MyLabel(QLabel):
def __init__(self):
super().__init__()
self.resize(300, 300)
self.setStyleSheet("background-color: cyan;")
def keyPressEvent(self, QKeyEvent):
print("xxx")
# 1. 创建一个应用程序对象
app = QApplication(sys.argv)
# 2. 控件操作
window = MyWidget()
label = MyLabel()
label.setParent(window)
label.grabKeyboard() # 让标签控件获取键盘事件
# 3. 展示控件
window.show()
# 4. 应用程序的执行,进入到消息循环
sys.exit(app.exec_())

0x0502:演示案例 — 监听用户输入指定单个按键
在下面这个案例中,我们想让 QLabel 标签捕获用户输入的指定单个按键,比如 Tab 键。示例代码如下:
import sys
from PyQt5.Qt import *
class MyWidget(QWidget):
def __init__(self):
super().__init__()
self.resize(800, 800)
def keyPressEvent(self, QKeyEvent):
print("zzz")
class MyLabel(QLabel):
def __init__(self):
super().__init__()
self.resize(300, 300)
self.setStyleSheet("background-color: cyan;")
def keyPressEvent(self, QKeyEvent):
# QKeyEvent.key() 获取键盘事件的键值
if (QKeyEvent.key() == Qt.Key_Tab): # Qt.Key_Tab 表示 Tab 键
print('用户点击了 Tab 键')
# 1. 创建一个应用程序对象
app = QApplication(sys.argv)
# 2. 控件操作
window = MyWidget()
label = MyLabel()
label.setParent(window)
label.grabKeyboard() # 让标签控件获取键盘事件
# 3. 展示控件
window.show()
# 4. 应用程序的执行,进入到消息循环
sys.exit(app.exec_())

0x0503:演示案例 — 监听用户输入指定组合键

在上面的案例中,我们捕获了单个按键的输入,那么这个案例,我们再补充一个 “组合键” 怎么获取,比如说 ctrl + s,ctrl + shift + A 怎么获取。
以 ctrl + shift + A 为例,三个按键里面,ctrl 与 shift 都是修饰键,因为单纯的点击 ctrl 或者单纯的点击 shift,页面上都不会出现对应的字符。分清了修饰键和有普通键后,我们再来补充一条 QKeyEvent 的方法:modifiers()。
modifiers() 函数可以捕获修饰键,多个修饰键之间需要使用按位或运算进行判断。直接上案例:
import sys
from PyQt5.Qt import *
class MyWidget(QWidget):
def __init__(self):
super().__init__()
self.resize(800, 800)
def keyPressEvent(self, QKeyEvent):
print("zzz")
class MyLabel(QLabel):
def __init__(self):
super().__init__()
self.resize(300, 300)
self.setStyleSheet("background-color: cyan;")
def keyPressEvent(self, QKeyEvent):
# 捕获 Ctrl + S 快捷键
if QKeyEvent.modifiers() == Qt.ControlModifier and QKeyEvent.key() == Qt.Key_S:
print("Ctrl + S 被按下了")
# 捕获 Ctrl + Alt + E 快捷键
if QKeyEvent.modifiers() == (Qt.ControlModifier | Qt.AltModifier) and QKeyEvent.key() == Qt.Key_E:
print("Ctrl + Alt + E 被按下了")
# 1. 创建一个应用程序对象
app = QApplication(sys.argv)
# 2. 控件操作
window = MyWidget()
label = MyLabel()
label.setParent(window)
label.grabKeyboard() # 让标签控件获取键盘事件
# 3. 展示控件
window.show()
# 4. 应用程序的执行,进入到消息循环
sys.exit(app.exec_())

702

被折叠的 条评论
为什么被折叠?



