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

 更新时间:2022年02月24日 08:31:15   作者:Python 集中营  
这篇文章主要和大家分享如何利用Python中的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()

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

if __name__ == "__main__":
    app = QApplication(sys.argv)
    form = PointerClock()
    form.show()
    app.exec_()

完整代码

# -*- 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动态时钟的资料请关注脚本之家其它相关文章!

相关文章

  • Python中decorator使用实例

    Python中decorator使用实例

    这篇文章主要介绍了Python中decorator使用实例,本文讲解了如何调用decorator、decorator函数的定义、decorator的应用场景等内容,需要的朋友可以参考下
    2015-04-04
  • python字符串常规操作大全

    python字符串常规操作大全

    这篇文章主要给大家介绍了关于python字符串常规操作的相关资料,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2021-05-05
  • python excel转换csv代码实例

    python excel转换csv代码实例

    这篇文章主要介绍了python excel转换csv代码实例,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下
    2019-08-08
  • Python新手学习过程记录之基础环境:环境变量、版本区分、虚拟环境

    Python新手学习过程记录之基础环境:环境变量、版本区分、虚拟环境

    刚开始接触Python开发语言,可能就会遇到一些棘手的问题,比如电脑上不知不觉已经安装了多个python版本,python3.8/3.10/3.11,甚至一些软件中也集成有python解释器;那么我编写的python代码,到底是使用哪个解释器在执行?我通过pip包管理工具安装的依赖包到底在那个地方
    2024-05-05
  • Python动态可视化模块Pynimate初体验

    Python动态可视化模块Pynimate初体验

    Pynimate是python第三方用于动态可视化的数据模块,是一位专攻 Python 语言的程序员开发的安装包。本文将通过几个简单的示例,讲解一下Pynimate的使用方法,需要的可以参考一下
    2023-02-02
  • Python利用redis-py实现集合与有序集合的常用指令操作

    Python利用redis-py实现集合与有序集合的常用指令操作

    这篇文章我们将来学习 redis-py 这个模块针对 “集合” 与 "有序集合"的一些常用指令操作,文中的示例代码讲解详细,需要的可以参考一下
    2022-09-09
  • Python通过Django实现用户注册和邮箱验证功能代码

    Python通过Django实现用户注册和邮箱验证功能代码

    这篇文章主要介绍了Python通过Django实现用户注册和邮箱验证功能代码,具有一定借鉴价值,需要的朋友可以参考下。
    2017-12-12
  • Python+Pygame实现简单的射击小游戏

    Python+Pygame实现简单的射击小游戏

    要说什么游戏能够获得大家的喜爱,唯射击游戏莫属!本文将利用Python和Pygame库制作一个简单的射击小游戏,感兴趣的小伙伴可以了解一下
    2022-04-04
  • Python学习之包与模块详解

    Python学习之包与模块详解

    在了解完面向对象与异常处理机制之后,本文将详细为大家介绍Python中的包与模块,文中的示例讲解详细,感兴趣的小伙伴可以学习一下
    2022-03-03
  • python readlines函数示例解析

    python readlines函数示例解析

    readlines()是Python文件对象的一个方法,用于读取文件中的所有行并将它们作为一个字符串列表返回,这篇文章主要介绍了python readlines函数解析,需要的朋友可以参考下
    2023-06-06

最新评论