要求:
1)模拟时钟的大小随着窗口大小变动,且成正圆
2)模拟时钟显示时针,分针和秒针,并且能对应当前时刻
3)秒针每隔一秒转动一格
4)模拟时钟有刻度,且5倍数的刻度比非5倍数的刻度长
思路分析:
这个时钟是个正圆,并且大小随着窗口变化,然后刻度也分长短。
1.需要根据当前窗口的大小来设置时钟的直径,取窗口尺寸中较小的那一个进行缩放
2.刻度一共有12个大刻度,然后没个刻度之间分为五个,一圈是360度,一共60个刻度,每个就是5度,没缝五的倍数是一个大刻度
3.接下来是指针的问题,获取当前的时间,然后计算出时针分针秒针相对于0点的角度,旋转画布画出来指针,再转回去
需要用到的包如下:
from PyQt5.QtCore import QTimer, QTime, Qt
from PyQt5.QtWidgets import QApplication, QWidget
from PyQt5.QtGui import QPainter, QPen
QTimer
:是 PyQt5 中用于创建定时器的类。它允许您执行延迟或重复的操作,并可以与其他 PyQt5 组件一起使用,例如窗口和小部件。通常用于执行周期性的任务或在一段时间后执行操作。
QTime
:是 PyQt5 中用于处理时间的类。它提供了获取当前时间、计算时间间隔等功能。在时钟应用程序中,通常会使用 QTime
来获取当前的小时、分钟和秒数,以便将时钟的指针移动到正确的位置。
Qt
:是 PyQt5 的一个子模块,包含了许多常用的枚举值、常量和函数。例如,Qt.black
表示黑色、Qt.red
表示红色等。这些常量通常用于设置颜色、布局和其他界面元素的属性。
QApplication
类是 PyQt5 中的一个重要类,它代表了整个应用程序。通常情况下,一个 PyQt5 应用程序只有一个 QApplication
实例。它提供了一个事件循环,用于接收和处理用户输入、操作系统事件等各种事件,并负责应用程序的初始化和退出。通过创建一个 QApplication
对象,可以启动 PyQt5 应用程序的事件循环,从而使应用程序开始运行。
QWidget
类是 PyQt5 中所有用户界面对象的基类。它用于创建窗口部件,例如按钮、文本框、标签等,或者作为其他用户界面元素的容器。QWidget
是所有用户界面元素的基础,几乎所有的用户界面元素都是从它派生出来的。通过创建一个 QWidget
对象,可以创建一个可视化的窗口或部件,并在其中添加其他用户界面元素。
QPainter
类是 PyQt5 中用于进行绘图操作的关键类之一。它提供了一系列绘制图形、文本、图像等的方法,可以用来在窗口或其他绘图设备上进行绘制操作。通过创建一个 QPainter
对象,并将其绑定到窗口或其他绘图设备上,您可以在这个设备上进行各种绘制操作。
QPen
类是 PyQt5 中用于设置画笔属性的类。画笔用于绘制直线、边框等图形元素的轮廓。QPen
类提供了设置画笔颜色、线宽、样式等属性的方法,以及一些用于控制画笔行为的其他方法。通过创建一个 QPen
对象,并将其设置为 QPainter
的当前画笔,您可以控制绘制操作的线条样式、颜色等属性。
1.根据当前窗口的大小来设置时钟的直径,取窗口尺寸中较小的那一个进行缩放
rect = min(self.width(), self.height())
painter = QPainter(self)
# 时钟外框
painter.translate(self.width() / 2, self.height() / 2) # 将坐标中心移动到窗口中心
painter.scale(rect / 200.0, rect / 200.0) # 根据窗口大小缩放
painter.setPen(Qt.black) # 黑色画笔
painter.drawEllipse(-100, -100, 200, 200) # 画圆 直径为200
2.刻度一共有12个大刻度,然后没个刻度之间分为五个,一圈是360度,一共60个刻度,每个就是5度,没缝五的倍数是一个大刻度
for i in range(0, 60):
if i % 5 == 0:
painter.drawLine(92, 0, 100, 0) # 画线,输入是起点和终点坐标 整时刻度
else:
painter.drawLine(97, 0, 100, 0) # 其他刻度
painter.rotate(6) # 每画一个刻度,旋转6度
3.接下来是指针的问题,获取当前的时间,然后计算出时针分针秒针相对于0点的角度,旋转画布画出来指针,再转回去。时针一分钟转0.5度,分针一秒钟转6度。
# 时针
painter.setPen(QPen(Qt.black, 5))
hour_angle = (time.hour() % 12 * 30 + time.minute() * 0.5) - 90 # 转换成角度
painter.rotate(hour_angle) # 画上指针
painter.drawLine(0, 0, 50, 0)
painter.rotate(-hour_angle) # 转回去 后面类似
# 分针
painter.setPen(QPen(Qt.black, 3))
minute_angle = time.minute() * 6 - 90
painter.rotate(minute_angle)
painter.drawLine(0, 0, 70, 0)
painter.rotate(-minute_angle)
# 秒针
painter.setPen(QPen(Qt.red, 2))
second_angle = time.second() * 6 - 90
painter.rotate(second_angle)
painter.drawLine(0, 0, 90, 0)
painter.rotate(-second_angle)
下面是全部代码
from PyQt5.QtCore import QTimer, QTime, Qt
from PyQt5.QtWidgets import QApplication, QWidget
from PyQt5.QtGui import QPainter, QPen
import sys
class AnalogClock(QWidget):
def __init__(self):
super().__init__()
self.setWindowTitle("时钟")
self.timer = QTimer(self) # 创建定时器
self.timer.timeout.connect(self.update) # 定时器的超时信号连接到self.update uodate会调用paintEvent来更新窗口
self.timer.start(1000) # 定时器的时间间隔设置为1秒
self.resize(400, 400) # 初始窗口大小
def paintEvent(self, event):
rect = min(self.width(), self.height())
painter = QPainter(self)
# 时钟外框
painter.translate(self.width() / 2, self.height() / 2) # 将坐标中心移动到窗口中心
painter.scale(rect / 200.0, rect / 200.0) # 根据窗口大小缩放
painter.setPen(Qt.black) # 黑色画笔
painter.drawEllipse(-100, -100, 200, 200) # 画圆 直径为200
# 获取当前时间
time = QTime.currentTime()
print(time)
# 刻度
for i in range(0, 60):
if i % 5 == 0:
painter.drawLine(92, 0, 100, 0) # 画线,输入是起点和终点坐标 整时刻度
else:
painter.drawLine(97, 0, 100, 0) # 其他刻度
painter.rotate(6) # 每画一个刻度,旋转6度
# 时针
painter.setPen(QPen(Qt.black, 5))
hour_angle = (time.hour() % 12 * 30 + time.minute() * 0.5) - 90 # 转换成角度
painter.rotate(hour_angle) # 画上指针
painter.drawLine(0, 0, 50, 0)
painter.rotate(-hour_angle) # 转回去 后面类似
# 分针
painter.setPen(QPen(Qt.black, 3))
minute_angle = time.minute() * 6 - 90
painter.rotate(minute_angle)
painter.drawLine(0, 0, 70, 0)
painter.rotate(-minute_angle)
# 秒针
painter.setPen(QPen(Qt.red, 2))
second_angle = time.second() * 6 - 90
painter.rotate(second_angle)
painter.drawLine(0, 0, 90, 0)
painter.rotate(-second_angle)
if __name__ == "__main__":
app = QApplication(sys.argv) # 应用程序的事件处理循环
clock = AnalogClock()
clock.show()
sys.exit(app.exec_())