Python实现三种风格的数字与模拟时钟示例

夏知夏
夏知夏
发布时间:2026-10-15| 5人浏览过
原创

本文通过Python的Turtle库展示了三种不同风格的时钟实现方式:包括基础的图形化时钟、带有指针的模拟时钟以及简易的数字时钟。文章详细解析了每种时钟的核心逻辑,如利用register_shape自定义指针、通过datetime获取系统时间以及利用ontimer实现动态刷新。适合希望学习Python图形界面编程及时间处理函数的开发者参考。

导语

时间流逝,我们要按时成长。

大家好,我是木子同学!今天隆重登场,欢迎交流~

你是否也有生物钟不准的时候?特别是在休息日或长假期间,时差感常常让人困扰。

对于大多数上班族而言,早起上班是最痛苦的事,但为了生活,这又是不可避免的现实。

今天,小编将通过代码示例,展示几种不同的时钟实现方式,希望能帮助大家更好地管理时间,准时上班,努力搞钱。

一、使用Turtle绘制基础时钟

1)代码展示

import turtle
from datetime import *
 
# 抬起画笔,向前运动一段距离放下
def Skip(step):
    turtle.penup()
    turtle.forward(step)
    turtle.pendown()
 
def mkHand(name, length):
    # 注册Turtle形状,建立表针Turtle
    turtle.reset()
    Skip(-length * 0.1)
    # 开始记录多边形的顶点。当前的乌龟位置是多边形的第一个顶点。
    turtle.begin_poly()
    turtle.forward(length * 1.1)
    # 停止记录多边形的顶点。当前的乌龟位置是多边形的最后一个顶点。将与第一个顶点相连。
    turtle.end_poly()
    # 返回最后记录的多边形。
    handForm = turtle.get_poly()
    turtle.register_shape(name, handForm)
 
def Init():
    global secHand, minHand, hurHand, printer
    # 重置Turtle指向北
    turtle.mode("logo")
    # 建立三个表针Turtle并初始化
    mkHand("secHand", 135)
    mkHand("minHand", 125)
    mkHand("hurHand", 90)
    secHand = turtle.Turtle()
    secHand.shape("secHand")
    minHand = turtle.Turtle()
    minHand.shape("minHand")
    hurHand = turtle.Turtle()
    hurHand.shape("hurHand")
 
    for hand in secHand, minHand, hurHand:
        hand.shapesize(1, 1, 3)
        hand.speed(0)
 
    # 建立输出文字Turtle
    printer = turtle.Turtle()
    # 隐藏画笔的turtle形状
    printer.hideturtle()
    printer.penup()
 
def SetupClock(radius):
    # 建立表的外框
    turtle.reset()
    turtle.pensize(7)
    for i in range(60):
        Skip(radius)
        if i % 5 == 0:
            turtle.forward(20)
            Skip(-radius - 20)
 
            Skip(radius + 20)
            if i == 0:
                turtle.write(int(12), align="center", font=("Courier", 14, "bold"))
            elif i == 30:
                Skip(25)
                turtle.write(int(i/5), align="center", font=("Courier", 14, "bold"))
                Skip(-25)
            elif (i == 25 or i == 35):
                Skip(20)
                turtle.write(int(i/5), align="center", font=("Courier", 14, "bold"))
                Skip(-20)
            else:
                turtle.write(int(i/5), align="center", font=("Courier", 14, "bold"))
            Skip(-radius - 20)
        else:
            turtle.dot(5)
            Skip(-radius)
        turtle.right(6)
 
def Week(t):  
    week = ["星期一", "星期二", "星期三",
            "星期四", "星期五", "星期六", "星期日"]
    return week[t.weekday()]
 
def Date(t):
    y = t.year
    m = t.month
    d = t.da
    return "%s %d%d" % (y, m, d)
 
def Tick():
    # 绘制表针的动态显示
    t = datetime.today()
    second = t.second + t.microsecond * 0.000001
    minute = t.minute + second / 60.0
    hour = t.hour + minute / 60.0
    secHand.setheading(6 * second)
    minHand.setheading(6 * minute)
    hurHand.setheading(30 * hour)
 
    turtle.tracer(False)
    printer.forward(65)
    printer.write(Week(t), align="center",
                  font=("Courier", 14, "bold"))
    printer.back(130)
    printer.write(Date(t), align="center",
                  font=("Courier", 14, "bold"))
    printer.hom()
    turtle.tracer(True)
 
    # 100ms后继续调用tick
    turtle.ontimer(Tick, 100)
 
def main():
    # 打开/关闭龟动画,并为更新图纸设置延迟。
    turtle.tracer(False)
    Init()
    SetupClock(160)
    turtle.tracer(True)
    Tick()
    turtle.mainloop()
 
if __name__ == "__main__":
    main()

2)效果展示

二、使用Turtle实现模拟时钟

1)代码展示

基本思路:通过自定义shape来绘制时针、分针和秒针。利用register_shape()函数注册指针形状,并通过shape类的setheading()函数设置指针角度。使用datetime.today()获取当前系统时间,结合ontimer()函数定义定时器事件以触发屏幕刷新,最后利用write()函数在屏幕上显示文本信息。

from turtle import *
from datetime import datetime
 
mode("logo") # 向上(北),正角度为顺时针
 
thisday = 0
thisecond = 0
 
second_hand = Turtle()
minute_hand = Turtle()
hour_hand = Turtle()
writer = Turtle()
writer.getscreen().bgcolor('gray90')
writer.color("gray20", "gray20")
 
def jump(distanz, winkel=0):
    penup()
    right(winkel)
    forward(distanz)
    left(winkel)
    pendown()
'''
laenge 指针长度
width 指针宽度
spitze 箭头边长
'''
def hand(laenge, spitze, width):
    lt(90)
    fd(width)
    rt(90)
    fd(laenge*1.15)
    rt(90)
    fd(width * 2)
    rt(90)
    fd(laenge*1.15)
    rt(90)
    fd(width)
    rt(90)
    fd(laenge*1.15)
    rt(90)
    fd(spitze/2.0)
    lt(120)
    fd(spitze)
    lt(120)
    fd(spitze)
    lt(120)
    fd(spitze/2.0)
 
def make_hand_shape(name, laenge, spitze, width):
    reset()
    jump(-laenge*0.15) # 指针靠近表盘中心的末端,但不与圆心重合
    begin_poly()
    hand(laenge, spitze, width)
    end_poly()
    hand_form = get_poly()
    register_shape(name, hand_form)
 
 
def clockface(radius):
    reset()
    # 外圆周
    pensize(2)
    colors = ['green3', 'green2', 'gray98']
    # 从外向内fill
    for i in range(3):
        jump(radius+7+(2-i)*4,90)
        fillcolor(colors[i])
        begin_fill()
        circle(radius+7+(2-i)*4, steps=1000)
        end_fill()
        jump(-radius-7-(2-i)*4,90)
 
    # 刻度
    pensize(7)
    color("gray60", "gray60")
    # 经验值
    params = [-35, -40, -40, -25, -15, -5, 0, -5, -15, -25, -40, -40] #距离
    angles = [0, -15, -25, -40, -35, -30, 0, 30, 35, 40, 25, 15] # 角度
    for i in range(60):
        jump(radius)
        if i % 5 == 0:
            fd(-15)
            # 下面三行写表盘数字
            jump(params[i/5], angles[i/5])
            write(12 if i/5==0 else i/5, align="center", font=("Courier", 20, "bold"))
            jump(params[i/5], 180+angles[i/5])
            jump(-radius+15)
        else:
            dot(3)
            jump(-radius)
        rt(6)
 
 
def setup():
    global second_hand, minute_hand, hour_hand, writer
    # 自定义形状
    make_hand_shape("hour_hand", 90, 25, 5)
    make_hand_shape("minute_hand",  130, 25, 3)
    make_hand_shape("second_hand", 140, 10, 1)
 
    # 画表盘
    clockface(160)
 
    hour_hand.shape("hour_hand")
    hour_hand.color("gray30", "gray12")
 
    minute_hand.shape("minute_hand")
    minute_hand.color("gray40", "blue")
 
    second_hand.shape("second_hand")
    second_hand.color("red4", "red4")
 
    for hand in hour_hand, minute_hand, second_hand:
        hand.resizemode("user")
        hand.shapesize(1, 1, 1)
        hand.speed(1)
    ht()
 
    writer.ht()
    writer.pu()
    writer.bk(85)
    
def wochentag():
    wochentag = ["星期一", "星期二", "星期三","星期四", "星期五", "星期六", "星期日"]
    return wochentag[t.weekday()]
 
def get_mmdd(z):
    m = z.month
    t = z.day
    return "%d月%d日" % (m, t)
 
def get_yyyy(z):
    j = z.year
    return "%d" % (j)
 
def write_date(t):
    global thisday
    x = t.day
    if thisday != x:
        thisday = x
        writer.clear()
        writer.home()
        writer.forward(65)
        writer.write(wochentag(t),
                 align="center", font=("Courier", 16, "bold"))
        writer.back(150)
        writer.write(get_mmdd(t),
                 align="center", font=("Courier", 16, "normal"))
        writer.back(15)
        writer.write(get_yyyy(t),
                 align="center", font=("Courier", 10, "normal"))
        writer.forward(100)
 
def tick():
    global thisecond
    t = datetime.today()
    if thisecond != t.second:
        thisecond = t.second
        #print t
        sekunde = t.second + t.microsecond * 0.000001
        minute = t.minute + sekunde / 60.0
        stunde = t.hour + minute / 60.0
        tracer(False)
        write_date(t)
        tracer(True)
        hour_hand.setheading(30 * stunde)
        minute_hand.setheading(6 * minute)
        second_hand.setheading(6 * sekunde)
    ontimer(tick, 10)
 
def main():
    tracer(False)
    setup()
    tracer(True)
    tick()
    return "EVENTLOOP"
 
if __name__ == "__main__":
    msg = main()
    print msg
    mainloop()

2)效果展示

三、简易数字时钟

1)代码展示

# coding=utf-8
import turtle
from datetime import *
 
 
# 由于表盘刻度不连续,需频繁抬起画笔,放下画笔
def skip(step):
    turtle.penup()  # 画笔抬起
    turtle.forward(step)  # 画笔移动step
    turtle.pendown()  # 画笔落下
 
 
# 建立表针,定制表针形状和名字
def make_hand(name, length):
    turtle.reset()
 
    skip(-length * 0.1)  # 表针一端,过表盘中心一小段,开始绘制
    turtle.begin_poly()  # 开始记录多边形的第一个顶点。
    turtle.forward(length * 1.1)  # 设置表针长度,绘制表针
    turtle.end_poly()  # 停止记录多边形的顶点。当前的乌龟位置是多边形的最后一个顶点。将与第一个顶点相连。
 
    handForm = turtle.get_poly()  # 返回最后记录的形状
 
    turtle.color('black')
    turtle.register_shape(name, handForm)
 
 
# 三个表针初始化,实例化
def init_hand():
    global sec_hand, min_hand, hou_hand, printer
    # 重置Turtle指向北
    turtle.mode("logo")  # logo:向上(北) 顺时针   standard:向右(东)  逆时针
 
    # 建立三个表针Turtle并初始化
    make_hand("sec_Hand", 135)
    make_hand("min_Hand", 110)
    make_hand("hou_Hand", 70)
 
    sec_hand = turtle.Turtle()
    sec_hand.shape("sec_Hand")
    min_hand = turtle.Turtle()
    min_hand.shape("min_Hand")
    hou_hand = turtle.Turtle()
    hou_hand.shape("hou_Hand")
 
    # 笔的属性
    for hand in sec_hand, min_hand, hou_hand:
        hand.shapesize(1, 1, 3)
        hand.speed(0)
 
    # 建立输出打印的文字Turtle
    printer = turtle.Turtle()
 
    # 隐藏画笔的turtle形状
    printer.hideturtle()
    printer.penup()
 
 
# 设置表盘
def set_clock(radius):
    turtle.reset()
    turtle.pencolor('red')  # 设置画笔颜色
    turtle.fillcolor('pink')  # 设置绘制图形的填充颜色
    turtle.pensize(10)  # 画笔宽度
 
    for i in range(60):
        skip(radius)
        # 逢五 使用线条并加粗
        if i % 5 == 0:
            turtle.forward(20)
            skip(-radius - 20)
            skip(radius + 20)
 
            # 设置数字的位置及字体,大小
            if i == 0:
                turtle.write(int(12), align="center", font=("Courier", 14, "bold"))
            elif i == 30:
                skip(25)
                turtle.write(int(i / 5), align="center", font=("Courier", 14, "bold"))
                skip(-25)
            elif i == 25 or i == 35:
                skip(20)
                turtle.write(int(i / 5), align="center", font=("Courier", 14, "bold"))
                skip(-20)
            else:
                turtle.write(int(i / 5), align="center", font=("Courier", 14, "bold"))
            skip(-radius - 20)
        # 非五,以点代替
        else:
            turtle.dot(5)
            skip(-radius)
        turtle.right(6)
 
 
# 显示星期
def show_week(t):
    week = ["星期一  Mon", "星期二  Tue", "星期三  Wed", "星期四  Thu", "星期五  Fri", "星期六  Sat", "星期日  Sun"]
    return week[t.weekday()]  # t.weekday() 周一为0,周二为1...可作为列表的index
 
 
# 显示日期
def show_data(t):
    y = t.year
    m = t.month
    d = t.day
    return "{} 年 {} 月 {} 日".format(y, m, d)
 
 
# 显示时间
# def show_time(t):
#     m = t.minute
#     h = t.hour
#     return "{}:{}".format(h, m)
 
 
# 显示整个时钟
def show_clock():
    # 获取时间
    t = datetime.today()
    second = t.second + t.microsecond * 0.000001
    minute = t.minute + second / 60.0
    hour = t.hour + minute / 60.0
 
    sec_hand.setheading(6 * second)
    min_hand.setheading(6 * minute)
    hou_hand.setheading(30 * hour)
 
    turtle.tracer(False)
 
    printer.forward(65)
    printer.write(show_week(t), align='center', font=("Courier", 14, "bold"))
 
    printer.back(65)
    printer.write("The Clock of Hua", align="center", font=("Courier", 16, "bold"))
 
    printer.back(65)
    printer.write(show_data(t), align='center', font=("Courier", 14, "bold"))
 
    # printer.back(25)
    # printer.write(show_time(t), align="center", font=("Courier", 14, "bold"))
    # 回到原点,以便于下一轮的显示
    printer.home()
    turtle.tracer(True)
 
    # 100ms后继续调用show_clock
    turtle.ontimer(show_clock, 100)
 
 
# main函数
def main():
    turtle.tracer(False)
    # 设置背景
    ts = turtle.getscreen()
    ts.bgcolor("#cccccc")
    # 初始化
    init_hand()
    # 设置时钟
    set_clock(180)
    turtle.tracer(True)
    # 显示时钟
    show_clock()
    turtle.mainloop()
 
 
if __name__ == "__main__":
    main()

2)效果展示

以上就是基于Python制作三款时钟的示例代码的详细内容,更多关于Python时钟制作的资料请关注本站其它相关文章!

相关标签:

免责声明:本文内容仅供参考,不代表本站观点。转载或引用请注明出处。

Python 相关产品和应用

全部下载
Selenium

Selenium

4.51.0 · Windows

用于浏览器自动化和 Web 测试的 Python 工具。

scikit-learn

scikit-learn

1.9.1 · Windows

常用 Python 机器学习算法与模型评估工具库。

Black

Black

26.10.1 · Windows

强调一致性的 Python 自动代码格式化工具。

Ruff

Ruff

0.17.1 · macOS

由 Rust 编写的高速 Python 代码检查和格式化工具。

pytest

pytest

9.1.1 · Windows

简洁而强大的 Python 自动化测试框架。

FastAPI

FastAPI

0.146.0 · Windows

高性能 Python API 框架,支持类型提示和自动接口文档。

Flask

Flask

3.1.3 · Windows

轻量灵活的 Python Web 应用框架。

Django

Django

6.1.2 · Windows

成熟的 Python Web 框架,适合构建内容站点和业务系统。

Spyder

Spyder

6.1.7 · Windows

面向科学计算与数据分析的 Python 集成开发环境。

SciPy

SciPy

1.18.1 · Windows

面向科学、工程和技术计算的 Python 算法库。