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

0x01:QObject 定时器 --- 方法详解

0x0101:startTimer() & timerEvent()
1. 正常示例 --- 通过 obj.timerEvent 设置触发事件
QObject 提供的 startTimer()
方法可以启动一个定时器,配合 QObject 类中的 timerEvent()
方法可以定时执行 timerEvent()
方法中指定的任务。看下面这个示例代码:
python
import sys
from PyQt5.Qt import *
# 1. 创建一个应用程序对象
app = QApplication(sys.argv)
# 2. 创建一个窗口对象
window = QWidget()
window.setWindowTitle("QObject 定时器使用")
obj = QObject()
timer_id = obj.startTimer(1000) # 每隔 1 秒,都会去执行 obj 内的 timerEvent 方法
obj.timerEvent = lambda event: print("定时器触发") # 定时器触发,会调用这个方法
# 3. 展示窗口
window.show()
# 4. 应用程序的执行,进入到消息循环
sys.exit(app.exec_())

2. 正常示例 --- 通过子类重写的方式设置触发事件
在上面那个案例中,我们是通过 obj.timerEvent()
方式直接设置的定时器触发时执行的代码,除了上面那种方法外,我们还可以通过子类重写的方式来设置触发的事件,通过这种方式我们的可操作性更大(因为 timerEvent()
毕竟是系统提供的 QObject 类的方法,我们不建议直接修改系统提供的类):
python
import sys
from PyQt5.Qt import *
class MyObject(QObject):
def timerEvent(self, event):
print("定时器触发")
# 1. 创建一个应用程序对象
app = QApplication(sys.argv)
# 2. 创建一个窗口对象
window = QWidget()
window.setWindowTitle("QObject 定时器使用")
obj = MyObject()
timer_id = obj.startTimer(1000) # 每隔 1 秒,都会去执行 obj 内的 timerEvent 方法
# 3. 展示窗口
window.show()
# 4. 应用程序的执行,进入到消息循环
sys.exit(app.exec_())

0x0102:killTimer(timer_id)
killTimer(timer_id)
支持根据传入的定时器 ID,杀死指定的定时器。比如下面这个示例,因为我们前脚启动完定时器,后脚就给它关闭了,所以窗口上啥也没打印:
python
import sys
from PyQt5.Qt import *
class MyObject(QObject):
def timerEvent(self, event):
print("定时器触发")
# 1. 创建一个应用程序对象
app = QApplication(sys.argv)
# 2. 创建一个窗口对象
window = QWidget()
window.setWindowTitle("QObject 定时器使用")
obj = MyObject()
timer_id = obj.startTimer(1000) # 每隔 1 秒,都会去执行 obj 内的 timerEvent 方法
obj.killTimer(timer_id) # 停止定时器
# 3. 展示窗口
window.show()
# 4. 应用程序的执行,进入到消息循环
sys.exit(app.exec_())

0x02:QObject 定时器 --- 案例演示
0x0201:倒计时案例

在这个案例中笔者封装了一个 TimingLabel(QLabel)
类来完成整个倒计时的工作,MyWIndow 类相当于是一个展示窗口的类。在实战中,我们也可以像这样,把你用的一个个小控件封装成一个个类,这样随着积累,你能收获一堆好用的小控件:
python
import sys
from PyQt5.Qt import *
class TimingLabel(QLabel):
"""
定时 Label 类, 高度的封装会造成代码的扩展性性降低
"""
def __init__(self, *args, **kwargs):
"""
为了通用,所以使用 *args, **kwargs 来接收参数
"""
# 调用父类的初始化方法进行初始化操作
super().__init__(*args, **kwargs)
self.move(285, 175)
self.setStyleSheet("font-size: 30px;")
self.setText("10")
self.timer_id = self.startTimer(1000) # 启动定时器
def timerEvent(self, *args, **kwargs):
# 1. 获取当前标签的内容
current_sec = int(self.text()) # 获取当前的秒数
current_sec -= 1
# 2. 设置当前的秒数
self.setText(str(current_sec))
# 3. 判断是否结束
if current_sec == 0:
# 3.1 停止定时器
self.killTimer(self.timer_id)
class MyWindow(QWidget):
def __init__(self):
super().__init__()
self.setWindowTitle("QObject 定时器使用")
self.init_ui()
def init_ui(self):
# 创建一个窗口
widget = QWidget(self)
widget.resize(600, 350)
# 创建一个定时 label
label = TimingLabel(widget)
# 1. 创建一个应用程序对象
app = QApplication(sys.argv)
# 2. 创建一个窗口对象
window = MyWindow()
# 3. 展示窗口
window.show()
# 4. 应用程序的执行,进入到消息循环
sys.exit(app.exec_())

0x0202:窗口增大案例

上面这个案例比较简单,直接秒了,难点可能就在于如何获得当前窗口的大小上:
python
import sys
from PyQt5.Qt import *
class MyWindow(QWidget):
def __init__(self):
super().__init__()
self.setWindowTitle("QObject 定时器使用")
self.init_ui()
def init_ui(self):
self.startTimer(100) # 开启定时任务,会定时执行 timerEvent 方法
def timerEvent(self, *args, **kwargs):
current_w = self.width()
current_h = self.height()
self.resize(current_w + 1, current_h + 1) # 每次定时任务触发,窗口大小增加 1
# 1. 创建一个应用程序对象
app = QApplication(sys.argv)
# 2. 创建一个窗口对象
window = MyWindow()
# 3. 展示窗口
window.show()
# 4. 应用程序的执行,进入到消息循环
sys.exit(app.exec_())
