使用Python的Turtle库制作数字时钟

Turtle库简介

Turtle是Python的一个标准库,用于绘制图形和创建简单的动画。它最初是Logo语言的一部分,被设计用来教授编程概念,特别是递归和过程调用。在Python中,Turtle库提供了一个简单易用的绘图环境,适合初学者理解和实践编程逻辑。

基本使用

Turtle库允许开发者创建多个“海龟”(Turtle),每个海龟都有自己的画笔,可以移动、旋转、抬起或放下画笔,从而在屏幕上绘制出各种形状。海龟的移动轨迹可以被记录下来作为多边形的顶点,这样就可以创建自定义形状。

代码详细解释

下面我们将逐步解析如何使用Turtle库创建一个带有动态指针的数字时钟。

  1. 定义辅助函数

    Skip函数用于移动海龟而不留下痕迹。mkHand函数用于创建时钟的手(秒针、分针、时针)形状,并注册为Turtle的形状。

  2. 初始化

    Init函数设置Turtle的工作模式,创建并初始化三个海龟(分别代表秒针、分针和时针),并设置它们的速度为最快。

  3. 设置时钟

    SetupClock函数绘制时钟的圆圈和刻度,包括小时标记和分钟标记。

  4. 显示日期和星期

    WeekDate函数用于获取当前的星期和日期,以便在时钟上显示。

  5. 动态更新

    Tick函数是定时器回调函数,它读取当前时间,更新时钟指针的位置,并重新绘制星期和日期。此函数会在每次调用后安排自己再次调用,以保持时钟的动态显示。

  6. 主函数

    main函数初始化屏幕,设置时钟布局,并启动定时器。

效果图

在这里插入图片描述

完整代码
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.day
    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.home()
    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()

结论

通过这个项目,我们不仅学习了Turtle库的基本用法,还掌握了如何利用Python处理时间和日期,以及如何在图形界面中动态更新内容。这不仅是一个有趣的小项目,也是一个很好的编程练习,帮助加深对Python语言特性的理解。

posted @   燕鹏  阅读(71)  评论(0编辑  收藏  举报  
(评论功能已被禁用)
相关博文:
阅读排行:
· 无需6万激活码!GitHub神秘组织3小时极速复刻Manus,手把手教你使用OpenManus搭建本
· C#/.NET/.NET Core优秀项目和框架2025年2月简报
· Manus爆火,是硬核还是营销?
· 终于写完轮子一部分:tcp代理 了,记录一下
· 【杭电多校比赛记录】2025“钉耙编程”中国大学生算法设计春季联赛(1)
点击右上角即可分享
微信分享提示