代码
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生成实现的,暂未在程序中体现。
具体实现过程如下:
-
在
__init__
方法中进行一些初始化操作,包括:- 绑定信号
update_ui_signal
与槽函数draw_time
; - 定义时、分、秒的变量并初始化为 0;
- 获取窗口对象及其控件,设置阴影效果、载入表盘图片、计算表盘中心坐标、定义时针、分针、秒针的坐标点信息等。
- 绑定信号
-
draw_time
方法被信号槽机制调用,以时间字符串作为参数。该方法首先根据时间字符串解析出时、分、秒的值,然后将时间字符串的前 8 位显示到 lcdNumber_date 控件中,将时间字符串的后 8 位显示到 lcdNumber 控件中。接着,重新载入表盘图片,并创建 QPainter 对象,在表盘上绘制时针、分针、秒针,并在最后结束 QPainter。 -
run
方法是QThread
类中的虚函数,自动调用该方法以启动线程。在run
方法中,使用一个无限循环,不断地轮询睡眠 1 秒钟,并等待主线程(ui线程)下发任务。每当有时间信号发送时,就会执行draw_time
方法更新时针、分针、秒针的位置,并在表盘上绘制出来。 -
一些注意事项是,目前没有进行页面的自适应,需要自行修改代码实现;相对位置也是使用的绝对坐标,需要修改
素材
分别是效果图原图和抠图后的素材,直接在QtDesigner的lcdNumber的背景图路径中修改为抠图的素材路径即可
注:本文除代码外大部分内容由GPT-3.5生成