脚本之家,脚本语言编程技术及教程分享平台!
分类导航

Python|VBS|Ruby|Lua|perl|VBA|Golang|PowerShell|Erlang|autoit|Dos|bat|

服务器之家 - 脚本之家 - Python - 基于PyQt5制作一个动态指针时钟

基于PyQt5制作一个动态指针时钟

2022-10-12 11:28Python 集中营 Python

这篇文章主要和大家分享如何利用Python中的PyQt5制作一个动态指针时钟来显示实时时间,文中的示例代码讲解详细,需要的可以参考一下

基于PyQt5制作一个动态指针时钟

想实现这样一个功能,然后pyqt5中又没有现成的组件可以使用,于是就想着只能通过绘图的方式来实现。说到绘图的话,turtle框架无疑是最常见的选择,但其实通过pyqt5的QPainter组件也是可以实现的。而且最后呈现出来的效果还是挺漂亮的。

实现思路:通过使用pyqt5的QPainter组件来绘制好时钟的图表,最后通过定时器不断的改变当前当前时间在图表上面的显示位置。这样最终就实现了一个指针时钟在不断的走动的过程。

和前面的UI应用一样,我们用到的UI相关的组件库还是这三个。

?
1
2
3
from PyQt5.QtCore import *
from PyQt5.QtGui import *
from PyQt5.QtWidgets import *

这次新使用了一个数学计算库,因为牵扯到数据计算相关的部分。

?
1
from math import *

应用操作相关的模块

?
1
import sys

动态时钟的主要实现过程我放在下面了,有需要的朋友可以自己研究一下。

?
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
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
class PointerClock(QWidget):
    def __init__(self):
        super().__init__()
        self.setWindowTitle("动态指针时钟  公众号:[Python 集中营]")
        self.setWindowIcon(QIcon('clock.ico'))
        self.timer = QTimer()
        # 设置窗口计时器
        self.timer.timeout.connect(self.update)
        self.timer.start(1000)
 
    def paintEvent(self, event):
        '''
        实时刷新指针图像
        :param event:
        :return:
        '''
        '''分别定义小时、分钟、秒钟的坐标点'''
        '''
        QPoint(int x, int y);创建坐标点,x、y分别代表横坐标、纵坐标
        '''
        hour_point = [QPoint(7, 8), QPoint(-7, 8), QPoint(0, -30)]
        min_point = [QPoint(7, 8), QPoint(-7, 8), QPoint(0, -65)]
        secn_point = [QPoint(7, 8), QPoint(-7, 8), QPoint(0, -80)]
 
        '''定义三种颜色、用于后面设置三种指针的颜色'''
        hour_color = QColor(182, 98, 0, 182)
        min_color = QColor(0, 130, 130, 155)
        sec_color = QColor(0, 155, 227, 155)
 
        '''获取QWidget对象的宽度和长度的最小值'''
        min_size = min(self.width(), self.height())
 
        painter = QPainter(self# 创建坐标系图像绘制对象
        painter.setRenderHint(QPainter.Antialiasing)
 
        # 将QWidget对象的中心位置作为绘制的中心坐标点
        painter.translate(self.width() / 2, self.height() / 2)
 
        # 对尺寸进行缩放
        painter.scale(int(min_size / 200), int(min_size / 200))
 
        # 保存状态
        painter.save()
 
        '''绘制时钟表盘的时间刻度线'''
 
        for a in range(0, 60):
            if (a % 5) != 0:
                # 每1/60绘制一个刻度线作为分钟刻度线
                painter.setPen(min_color)
                painter.drawLine(92, 0, 96, 0)
            else:
                # 每5/60绘制一个刻度线作为小时刻度线
                painter.setPen(hour_color)
                painter.drawLine(88, 0, 96, 0# 绘制小时刻度线
            # 每分钟旋转6度
            painter.rotate(360 / 60)
        # 恢复状态
        painter.restore()
 
        '''绘制时钟表盘上面的数字'''
        # 保存状态
        painter.save()
        # 获取字体对象
        font = painter.font()
        # 设置粗体
        font.setBold(True)
        painter.setFont(font)
        # 获取字体大小
        font_size = font.pointSize()
        # 设置之前定义好的颜色
        painter.setPen(hour_color)
        hour_num = 0
        radius = 100
        for i in range(0, 12):
            # 按照12小时制,每三个小时绘制一个小时数字,需要遍历4次
            hour_num = i + 3  # 按QT-Qpainter的坐标系换算,3小时的刻度线对应坐标轴0度
            if hour_num > 12:
                hour_num = hour_num - 12
            # 根据字体的大小计算出写入小时数字的x、y的位置
            x = radius * 0.8 * cos(i * 30 * pi / 180.0) - font_size
            y = radius * 0.8 * sin(i * 30 * pi / 180.0) - font_size / 2.0
            width = font_size * 2
            height = font_size
            painter.drawText(QRectF(x, y, width, height), Qt.AlignCenter, str(hour_num))
        # 恢复状态
        painter.restore()
 
        '''绘制时钟表盘的时、分、秒的指针'''
 
        # 获取当前时间
        time = QTime.currentTime()
 
        # 绘制小时指针
        painter.save()
        # 取消轮廓线
        painter.setPen(Qt.NoPen)
        # 设置小时指针的颜色
        painter.setBrush(hour_color)
        # 小时指针逆时针旋转
        painter.rotate(30 * (time.hour() + time.minute() / 60))
        # 绘制时钟指针
        painter.drawConvexPolygon(QPolygonF(hour_point))
        # 恢复状态
        painter.restore()
 
        # 绘制分钟指针
        painter.save()
        # 取消轮廓线
        painter.setPen(Qt.NoPen)
        # 设置分钟指针的颜色
        painter.setBrush(min_color)
        # 分钟指针逆时针旋转
        painter.rotate(6 * (time.minute() + time.second() / 60))
        # 绘制分钟指针
        painter.drawConvexPolygon(QPolygonF(min_point))
        # 恢复状态
        painter.restore()
 
        # 绘制秒钟指针
        painter.save()
        # 取消轮廓线
        painter.setPen(Qt.NoPen)
        # 设置秒针颜色
        painter.setBrush(sec_color)
        # 秒钟指针逆时针旋转
        painter.rotate(6 * time.second())
        # 绘制秒钟指针
        painter.drawConvexPolygon(QPolygonF(secn_point))
        # 恢复状态
        painter.restore()

最后,还是通过main()函数直接启动整个App。

?
1
2
3
4
5
if __name__ == "__main__":
    app = QApplication(sys.argv)
    form = PointerClock()
    form.show()
    app.exec_()

完整代码

?
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
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
# -*- coding:utf-8 -*-
# @author Python 集中营
# @date 2022/1/25
# @file test9.py
 
# done
 
 
# 利用pyqt5制作指针钟表显示实施时间
 
# 想实现这样一个功能,然后pyqt5中又没有现成的组件可以使用,于是就想着只能通过绘图的方式来实现。
# 说到绘图的话,turtle框架无疑是最常见的选择,但其实通过pyqt5的QPainter组件也是可以实现的。而且最后呈现出来的
# 效果还是挺漂亮的。
 
# 实现思路:通过使用pyqt5的QPainter组件来绘制好时钟的图表,最后通过定时器不断的改变当前当前时间在图表上面的显示位置。
# 这样最终就实现了一个指针时钟在不断的走动的过程。
 
# 和前面的UI应用一样,我们用到的UI相关的组件库还是这三个。
from PyQt5.QtCore import *
from PyQt5.QtGui import *
from PyQt5.QtWidgets import *
 
# 这次新使用了一个数学计算库,因为牵扯到数据计算相关的部分。
from math import *
 
# 应用操作相关的模块
import sys
 
 
class PointerClock(QWidget):
    def __init__(self):
        super().__init__()
        self.setWindowTitle("动态指针时钟  公众号:[Python 集中营]")
        self.setWindowIcon(QIcon('clock.ico'))
        self.timer = QTimer()
        # 设置窗口计时器
        self.timer.timeout.connect(self.update)
        self.timer.start(1000)
 
    def paintEvent(self, event):
        '''
        实时刷新指针图像
        :param event:
        :return:
        '''
        '''分别定义小时、分钟、秒钟的坐标点'''
        '''
        QPoint(int x, int y);创建坐标点,x、y分别代表横坐标、纵坐标
        '''
        hour_point = [QPoint(7, 8), QPoint(-7, 8), QPoint(0, -30)]
        min_point = [QPoint(7, 8), QPoint(-7, 8), QPoint(0, -65)]
        secn_point = [QPoint(7, 8), QPoint(-7, 8), QPoint(0, -80)]
 
        '''定义三种颜色、用于后面设置三种指针的颜色'''
        hour_color = QColor(182, 98, 0, 182)
        min_color = QColor(0, 130, 130, 155)
        sec_color = QColor(0, 155, 227, 155)
 
        '''获取QWidget对象的宽度和长度的最小值'''
        min_size = min(self.width(), self.height())
 
        painter = QPainter(self# 创建坐标系图像绘制对象
        painter.setRenderHint(QPainter.Antialiasing)
 
        # 将QWidget对象的中心位置作为绘制的中心坐标点
        painter.translate(self.width() / 2, self.height() / 2)
 
        # 对尺寸进行缩放
        painter.scale(int(min_size / 200), int(min_size / 200))
 
        # 保存状态
        painter.save()
 
        '''绘制时钟表盘的时间刻度线'''
 
        for a in range(0, 60):
            if (a % 5) != 0:
                # 每1/60绘制一个刻度线作为分钟刻度线
                painter.setPen(min_color)
                painter.drawLine(92, 0, 96, 0)
            else:
                # 每5/60绘制一个刻度线作为小时刻度线
                painter.setPen(hour_color)
                painter.drawLine(88, 0, 96, 0# 绘制小时刻度线
            # 每分钟旋转6度
            painter.rotate(360 / 60)
        # 恢复状态
        painter.restore()
 
        '''绘制时钟表盘上面的数字'''
        # 保存状态
        painter.save()
        # 获取字体对象
        font = painter.font()
        # 设置粗体
        font.setBold(True)
        painter.setFont(font)
        # 获取字体大小
        font_size = font.pointSize()
        # 设置之前定义好的颜色
        painter.setPen(hour_color)
        hour_num = 0
        radius = 100
        for i in range(0, 12):
            # 按照12小时制,每三个小时绘制一个小时数字,需要遍历4次
            hour_num = i + 3  # 按QT-Qpainter的坐标系换算,3小时的刻度线对应坐标轴0度
            if hour_num > 12:
                hour_num = hour_num - 12
            # 根据字体的大小计算出写入小时数字的x、y的位置
            x = radius * 0.8 * cos(i * 30 * pi / 180.0) - font_size
            y = radius * 0.8 * sin(i * 30 * pi / 180.0) - font_size / 2.0
            width = font_size * 2
            height = font_size
            painter.drawText(QRectF(x, y, width, height), Qt.AlignCenter, str(hour_num))
        # 恢复状态
        painter.restore()
 
        '''绘制时钟表盘的时、分、秒的指针'''
 
        # 获取当前时间
        time = QTime.currentTime()
 
        # 绘制小时指针
        painter.save()
        # 取消轮廓线
        painter.setPen(Qt.NoPen)
        # 设置小时指针的颜色
        painter.setBrush(hour_color)
        # 小时指针逆时针旋转
        painter.rotate(30 * (time.hour() + time.minute() / 60))
        # 绘制时钟指针
        painter.drawConvexPolygon(QPolygonF(hour_point))
        # 恢复状态
        painter.restore()
 
        # 绘制分钟指针
        painter.save()
        # 取消轮廓线
        painter.setPen(Qt.NoPen)
        # 设置分钟指针的颜色
        painter.setBrush(min_color)
        # 分钟指针逆时针旋转
        painter.rotate(6 * (time.minute() + time.second() / 60))
        # 绘制分钟指针
        painter.drawConvexPolygon(QPolygonF(min_point))
        # 恢复状态
        painter.restore()
 
        # 绘制秒钟指针
        painter.save()
        # 取消轮廓线
        painter.setPen(Qt.NoPen)
        # 设置秒针颜色
        painter.setBrush(sec_color)
        # 秒钟指针逆时针旋转
        painter.rotate(6 * time.second())
        # 绘制秒钟指针
        painter.drawConvexPolygon(QPolygonF(secn_point))
        # 恢复状态
        painter.restore()
 
 
if __name__ == "__main__":
    app = QApplication(sys.argv)
    form = PointerClock()
    form.show()
    app.exec_()

以上就是基于PyQt5制作一个动态指针时钟的详细内容,更多关于PyQt5动态时钟的资料请关注服务器之家其它相关文章!

原文链接:https://www.cnblogs.com/lwsbc/p/15929520.html

延伸 · 阅读

精彩推荐