Pyqt案例(一)计时器

本例包含内容:自定义信号、多线程、QLCDNumber

简单,适合当范例,忘记时候回来看看

ChatGPT能帮助解读代码

源码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
import sys

from PySide6.QtCore import *
from PySide6.QtWidgets import *

sec = 0 # 时间:s/秒

# 计时线程,发送信号给Counter
class TimeThread(QThread):
timer = Signal() # timer每过一秒发送信号
end = Signal() # end计时结束发送信号

def __init__(self):
super(TimeThread, self).__init__()

# 计时函数
def run(self):
while True:
self.sleep(1)
if sec == 5:
self.end.emit()
break
self.timer.emit()

# 计时器主界面
class Counter(QWidget):
def __init__(self):
super(Counter, self).__init__()

self.setWindowTitle("计数器")
self.resize(300,120)

# QLCDNumber一个显示数字的框
layout = QVBoxLayout()
self.lcd = QLCDNumber()
layout.addWidget(self.lcd)

# 计数开始按钮
self.butten = QPushButton('开始计数')
layout.addWidget(self.butten)

# 垂直布局放到按钮中
self.setLayout(layout)

# 计时线程
self.timeThread = TimeThread()

# 链接信号与槽
self.timeThread.timer.connect(self.countTime)
self.timeThread.end.connect(self.end)
self.butten.clicked.connect(self.workThread)

# 当开始按钮click时,运行线程
def workThread(self):
self.timeThread.start()

# 计时,每过一秒timer发送信号,sec加1
def countTime(self):
global sec
sec+=1
self.lcd.display(sec)

# 计时结束,end发送信号,弹出结束对话框
def end(self):
QMessageBox.information(self,'消息','计时结束',QMessageBox.Ok)

if __name__ == "__main__":

app = QApplication(sys.argv)

window = Counter()

window.show()

sys.exit(app.exec())

问题

1
2
3
4
5
6
7
8
9
timer = Signal()
self.timeThread.timer.connect(self.countTime)
# connect方法并不是Signal对象中的方法,而是QObject中的。
# 我之前写在了__init__方法里
self.timer = Signal()
#...timer.connect()就会在Signal()中找connect方法
# 结果报错,Signal里根本没有connect
AttributeError: 'PySide6.QtCore.Signal' object has no attribute 'connect'
# 查了些资料没找到解释,chatGPT给的解释是,信号对象被创建时,会自动创建一个与之关联的信号通道。这个信号通道在内部维护了一个槽函数列表和一些其他信息。当调用 signal_object.connect(slot) 时,它实际上调用了信号通道内部的 connect 方法,将指定的槽函数添加到槽函数列表中。实现这一过程似乎是重写了__getattritube__方法。