使用PyQT实现模拟表盘时钟的显示效果

34 篇文章 0 订阅

代码

class clockThread(QThread):

    update_ui_signal = pyqtSignal(str)

    def __init__(self, window):
        super(clockThread, self).__init__()
        # 信号绑定槽函数
        self.update_ui_signal.connect(self.draw_time)
        self.hour = 0
        self.minute = 0
        self.second = 0

        self.window = window

        self.window.lcdNumber.setContextMenuPolicy(QtCore.Qt.DefaultContextMenu)
        self.window.lcdNumber.setFrameShape(QtWidgets.QFrame.NoFrame)
        # InsideWindow.lcdNumber.setDigitCount(9)
        # 创建阴影效果对象并设置偏移和颜色
        shadow = QGraphicsDropShadowEffect()
        shadow.setBlurRadius(5)
        shadow.setColor(QtGui.QColor(0, 0, 0, 255))
        shadow.setOffset(4, -3)
        # 将阴影效果应用于QLCDNumber的字体
        self.window.lcdNumber.setGraphicsEffect(shadow)

        image = QImage('pic/表盘原图抠图.png')
        self.pixmap = QPixmap.fromImage(image)

        rect = self.window.label_clock.geometry()
        self.center_x = int(rect.x() + rect.width() / 2)
        self.center_y = int(rect.y() + rect.height() / 2)

        self.hour_points = [QPoint(10, 0), QPoint(-10, 0), QPoint(0, -150)]
        self.minute_points = [QPoint(10, 0), QPoint(-10, 0), QPoint(0, -250)]
        self.second_points = [QPoint(10, 0), QPoint(-10, 0), QPoint(0, -300)]




    def draw_time(self, time_str):
        self.hour = int(time_str[-8:-6])
        self.minute = int(time_str[-5:-3])
        self.second = int(time_str[-2:])

        # print("-------------", self.hour, self.minute, self.second, time_str[:8])

        self.window.lcdNumber.display(time_str[-8:])
        self.window.lcdNumber_date.display(time_str[:8])

        self.window.label_clock.setPixmap(self.pixmap)

        self.painter = QtGui.QPainter(self.window.label_clock.pixmap())
        self.painter.setRenderHint(QPainter.Antialiasing)
        # print(self.center_x, self.center_y)
        self.painter.translate(self.center_x-20, self.center_y+180)  # 平移到label中心
        # self.painter.scale(1, 1)  # 进行尺度缩放

        # 绘制时针
        self.painter.setBrush(QColor(0, 0, 127))
        self.painter.save()
        self.painter.rotate(30.0*((self.hour + self.minute/60.0)))
        self.painter.drawConvexPolygon(QPolygon(self.hour_points))
        self.painter.restore()

        # 绘制分针
        self.painter.setBrush(QColor(0, 127, 127))
        self.painter.save()
        self.painter.rotate(6.0*(self.minute + self.second/60.0))
        self.painter.drawConvexPolygon(QPolygon(self.minute_points))
        self.painter.restore()

        # 绘制秒针
        self.painter.setBrush(QColor(150, 43, 5))
        self.painter.save()
        self.painter.rotate(6.0 * self.second)
        self.painter.drawConvexPolygon(QPolygon(self.second_points))
        self.painter.restore()

        self.painter.end()


    def run(self):
        while True:  # 让子线程一直运行,等待主线程(ui线程)下发的任务
            time.sleep(1)
            # print("clock thread")

效果

该代码定义了一个 clockThread 类,继承自 PyQt5 的 QThread 类。其主要功能是实现一个模拟时钟的线程,在这个线程中,通过 draw_time 方法更新时针、分针、秒针的位置,并在表盘上绘制出来,并将更新后的时间显示到 lcdNumber 控件中。

一些控件的定义和初始化直接使用QtDesigner生成实现的,暂未在程序中体现。

具体实现过程如下:

  1. __init__ 方法中进行一些初始化操作,包括:

    • 绑定信号 update_ui_signal 与槽函数 draw_time
    • 定义时、分、秒的变量并初始化为 0;
    • 获取窗口对象及其控件,设置阴影效果、载入表盘图片、计算表盘中心坐标、定义时针、分针、秒针的坐标点信息等。
  2. draw_time 方法被信号槽机制调用,以时间字符串作为参数。该方法首先根据时间字符串解析出时、分、秒的值,然后将时间字符串的前 8 位显示到 lcdNumber_date 控件中,将时间字符串的后 8 位显示到 lcdNumber 控件中。接着,重新载入表盘图片,并创建 QPainter 对象,在表盘上绘制时针、分针、秒针,并在最后结束 QPainter。

  3. run 方法是 QThread 类中的虚函数,自动调用该方法以启动线程。在 run 方法中,使用一个无限循环,不断地轮询睡眠 1 秒钟,并等待主线程(ui线程)下发任务。每当有时间信号发送时,就会执行 draw_time 方法更新时针、分针、秒针的位置,并在表盘上绘制出来。

  4. 一些注意事项是,目前没有进行页面的自适应,需要自行修改代码实现;相对位置也是使用的绝对坐标,需要修改

素材

分别是效果图原图和抠图后的素材,直接在QtDesigner的lcdNumber的背景图路径中修改为抠图的素材路径即可

注:本文除代码外大部分内容由GPT-3.5生成

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

大饼酱人

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值