用Python制作一个简单时间、日期显示工具

news2024/12/28 18:30:09

Python是一款强大的编程软件,可以轻松实现我们的多种开发需求。今天我们拿Python中自带的tkinter来开发一个时钟显示器。如下图所示:

时间显示器

一、编程要求

用tkinter写一个漂亮、五彩的时间显示器,要求显示时、分、秒,即时变化,同时显示日期,要小巧、精致,逻辑清晰,代码没有冗余,打开就能显示,不需要安装额外的包。

二、算法分析

如果不需要额外的包,就用Python自带的tkinter,这样打包以后形成的exe文件太会小巧、轻便,打开马上就可以用。首先,我们先用函数法来解决这个问题,然后我们再使用类的写法来进一步优化。

1. 采用函数法实现

在编写过程中,我们首先导入tkinter模块和所需的其他模块。

然后,我们定义了两个函数update_time()和update_date(),用于更新时间和日期的标签。update_time()函数使用time.strftime()函数获取当前时间,并使用config()方法将其更新到time_label上。

接着,我们使用after()方法在1000毫秒(1秒)后再次调用update_time()函数,以实现时间的即时变化。类似地,update_date()ref="http://函数使用datetime.date.today">函数使用datetime.date.today().strftime()获取当前日期,并更新到date_label上。

接下来,我们创建了一个tkinter的根窗口,并设置了窗口的标题、大小和背景颜色。然后,我们定义了用于时间和日期的字体,分别为大号的时间字体和小号的日期字体。

随后,我们创建了两个标签time_label和date_label,用于显示时间和日期。我们使用pack()方法将它们放置在窗口中心位置,并使用font参数设置它们的字体和背景颜色。

最后,我们分别调用update_time()和update_date()函数来开始更新时间和日期的显示。然后,通过调用root.mainloop()进入主事件循环,使窗口保持打开状态。

运行该代码,您将会看到一个小巧、精致的窗口,其中包含一个五彩的时间显示器和日期显示器。时间将以时、分、秒的形式显示,并且会实时更新。日期以年-月-日的形式显示,并且在窗口打开时就会显示当前日期。请注意,这里我们没有使用任何额外的包,仅使用了tkinter和标准库中的time和datetime模块。

import tkinter as tk
from tkinter import font
import time
import datetime

def update_time():
    current_time = time.strftime('%H:%M:%S')
    time_label.config(text=current_time)
    time_label.after(1000, update_time)

def update_date():
    current_date = datetime.date.today().strftime('%Y-%m-%d')
    date_label.config(text=current_date)

root = tk.Tk()
root.title("时间显示器")
root.geometry("300x200")
root.configure(bg='white')

time_font = font.Font(family="Helvetica", size=48, weight="bold")
date_font = font.Font(family="Helvetica", size=16)

time_label = tk.Label(root, text="", font=time_font, bg='white')
time_label.pack(pady=30)

date_label = tk.Label(root, text="", font=date_font, bg='white')
date_label.pack()

update_time()
update_date()

root.mainloop()

2. 采用类的写法来实现

当将代码转换为类的写法时,我们可以将主要的功能和界面元素封装在一个自定义的ClockApp类中。以下是使用类的方式编写的时间和日期显示器的代码示例:

import tkinter as tk
from tkinter import font
import time,datetime

class ClockApp(tk.Tk):
    def __init__(self):
        super().__init__()
        self.title("时间显示器")
        self.geometry("300x200")
        self.configure(bg='white')

        self.time_font = font.Font(family="Helvetica", size=48, weight="bold")
        self.date_font = font.Font(family="Helvetica", size=16)

        self.time_label = tk.Label(self, text="", font=self.time_font, bg='white')
        self.time_label.pack(pady=30)

        self.date_label = tk.Label(self, text="", font=self.date_font, bg='white')
        self.date_label.pack()

        self.update_time()
        self.update_date()

    def update_time(self):
        current_time = time.strftime('%H:%M:%S')
        self.time_label.config(text=current_time)
        self.time_label.after(1000, self.update_time)

    def update_date(self):
        current_date = datetime.date.today().strftime('%Y-%m-%d')
        self.date_label.config(text=current_date)

if __name__ == "__main__":
    app = ClockApp()
    app.mainloop()

在这个例子中,我们定义了一个继承自http://tk.Tk的ClockApp类。在__init__方法中,我们初始化了窗口的标题、大小和背景颜色,并创建了时间和日期标签,设置它们的字体和背景颜色。

update_time和update_date方法与之前的示例中的函数是相同的,用于更新时间和日期的显示。不同之处在于,我们使用self.time_label.afterself.date_label.after方法来周期性地调用这两个方法。

在代码的最后,我们创建了一个ClockApp对象并运行应用程序的主事件循环。

通过这种类的写法,我们将相关的功能组织在一起,使代码更加结构化和可扩展。

3. 采用表盘显示

以上时钟,仅是数字的显示,感觉还不够高端,可以改为一个表盘,上面写上珍惜时间的句子,然后最下面再写上时间和日期,效果可能会更好。如下图所示:

为了实现上述的功能,我们要做到以下几步:

创建一个继承自http://tkinter.Tk的ClockApp类,并初始化窗口的标题、大小和背景颜色。

在窗口中创建一个Canvas部件用于绘制表盘,并将其放置在窗口中。

创建一个Label部件用于显示时间,并将其放置在窗口中,设置其字体和背景颜色。

创建一个Label部件用于显示日期,并将其放置在窗口中,设置其字体和背景颜色。

调用draw_clock方法绘制表盘,包括表盘圆形和刻度线。

调用update_clock方法开始更新时钟。

在update_clock方法中,获取当前时间和日期。

使用strftime方法将时间格式化为字符串,并更新时间标签的文本内容。

使用strftime方法将日期格式化为字符串,并更新日期标签的文本内容。

计算时针、分针和秒针的位置和角度,并使用create_line方法在表盘上绘制它们。

如果存在上一次绘制的秒针图像对象,使用canvas.delete方法删除它。绘制新的秒针图像,并将其保存到self.second_hand成员变量中。

为了消除时针和分针的运动轨迹,我们在绘制时针和分针时,我们需要使用canvas.create_line方法创建新的图像对象,并将其保存到相应的成员变量中。

使用after方法设置一个定时器,每隔一秒钟调用update_clock方法更新时钟的显示。

通过这些步骤,我们创建了一个实时更新的时钟应用程序。它显示当前的时间和日期,并在表盘上绘制时针、分针和秒针,使它们根据实际时间进行更新。同时,修复了秒针、时针、分针的轨迹不消失的问题,确保秒针在更新时正常显示和消失。下面是优化后的时钟代码展示:

import tkinter as tk
from math import cos, sin, pi
from datetime import datetime

class ClockApp(tk.Tk):
    def __init__(self):
        super().__init__()
        self.title("表盘时钟")
        self.geometry("400x450")
        self.configure(bg='light green')

        self.motto_label = tk.Label(self, text="时不待我,只争朝夕!",font=('楷体', 16,'bold'), bg='light green')
        self.motto_label.pack()
        
        self.canvas = tk.Canvas(self, width=400, height=360, bg='light green', highlightthickness=0)
        self.canvas.pack()

        self.time_label = tk.Label(self, font=('Helvetica', 16), bg='light green')
        self.time_label.pack(pady=10)

        self.date_label = tk.Label(self, font=('Helvetica', 12), bg='light green')
        self.date_label.pack()

        self.hour_hand = None  # 保存时针图像对象
        self.minute_hand = None  # 保存分针图像对象
        self.second_hand = None  # 保存秒针图像对象

        self.draw_clock()
        self.update_clock()

    def draw_clock(self):
        center_x = 200
        center_y = 200
        radius = 150

        # 绘制表盘
        self.canvas.create_oval(center_x - radius, center_y - radius, center_x + radius, center_y + radius,
                                width=2, outline='blue')

        # 绘制刻度线和小时标识
        for i in range(12):
            angle = (i / 12) * 2 * pi
            x1 = center_x + cos(angle) * (radius - 10)
            y1 = center_y + sin(angle) * (radius - 10)
            x2 = center_x + cos(angle) * radius
            y2 = center_y + sin(angle) * radius
            self.canvas.create_line(x1, y1, x2, y2, width=3)
            hour_x = center_x + cos(angle) * (radius - 25)
            hour_y = center_y + sin(angle) * (radius - 25)
            self.canvas.create_text(hour_x, hour_y, text=str(i+1), font=('Helvetica', 12), fill='black')

    def update_clock(self):
        current_time = datetime.now().time()
        current_date = datetime.now().date()

        # 更新时间标签
        time_str = current_time.strftime('%H:%M:%S')
        self.time_label.config(text=time_str)

        # 更新日期标签
        date_str = current_date.strftime('%Y-%m-%d')
        self.date_label.config(text=date_str)

        # 删除上一次的时针和分针图像
        if self.hour_hand:
            self.canvas.delete(self.hour_hand)
        if self.minute_hand:
            self.canvas.delete(self.minute_hand)

        # 更新时针
        hour = current_time.hour
        minute = current_time.minute
        second = current_time.second

        hour_angle = ((hour % 12) + minute / 60 + second / 3600) * (2 * pi / 12) - pi / 2
        hour_length = hour_x = 200 + cos(hour_angle) * 60
        hour_y = 200 + sin(hour_angle) * 60
        self.hour_hand = self.canvas.create_line(200, 200, hour_x, hour_y, width=4, fill='brown')
        
            # 更新分针
        minute_angle = ((minute + second / 60) / 60) * (2 * pi) - pi / 2
        minute_length = 90
        minute_x = 200 + cos(minute_angle) * minute_length
        minute_y = 200 + sin(minute_angle) * minute_length
        self.minute_hand = self.canvas.create_line(200, 200, minute_x, minute_y, width=3, fill='green')

        # 更新秒针
        second_angle = (second / 60.0) * (2 * pi) - pi / 2
        second_length = 120
        second_x = 200 + cos(second_angle) * second_length
        second_y = 200 + sin(second_angle) * second_length
        if self.second_hand:
            self.canvas.delete(self.second_hand)
        self.second_hand = self.canvas.create_line(200, 200, second_x, second_y, width=2, fill='red')

        self.after(1000, self.update_clock)
if __name__ == "__main__":
    app = ClockApp()
    app.mainloop()

三、学后反思

  1. 函数法和类的写法都可以完成任务,但是相比起来类的写法更加科学、富有逻辑性,后期如何再添加功能也很容易实现。推荐用类的写法。
  2. 函数的命名要与其功能相一致,从名字上要一下子就可以看出函数的功能,如update_time()函数就是更新时间显示。
  3. 如果定义一下label可以定义成用途+属性,比如时间的标签就可以定义为time_label,这样才更容易识别。
  4. 如果遇到复杂的编程可以先画一个思维导图,明确用途、实现步骤等,再逐步实现编程。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/710225.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

【JAVA】十分钟带你了解java的前世今生

个人主页:【😊个人主页】 系列专栏:【初始JAVA】 文章目录 前言JAVA介绍诞生🔬名字与图标🤖发展🛩️未来🪄 前言 玩过我的世界的朋友想必对JAVA以及它的图标都很熟悉,在游戏开始画面…

Java程序所在机器性能监控

Java程序所在机器性能监控 背景 问题单:程序故障(OOM、网络不通、操作卡顿)问题单:服务连接不上需求 1、监控本地机器性能 告警日志UI2、监控服务接口服务 告警日志UI方案 固定间隔获取机器网络CPU内存数据设置阈值,告…

自定义starter实现接口或方法限流功能

本文的思路是利用AOP技术自定义注解实现对特定的方法或接口进行限流。目前通过查阅相关资料,整理出三种类型限流方法,分别为基于guava限流实现、基于sentinel限流实现、基于Semaphore的实现。 一、限流常用的算法 1.1令牌桶算法 令牌桶算法是目前应用…

OpenCV(视频加载与摄像头使用)

目录 1、VideoCapture类 2、视频属性get() 3、视屏文件保存 1、VideoCapture类 2、视频属性get() 3、视屏文件保存 //视频的读取保存 int test3() {VideoCapture video;//video.open("F:/testMap/lolTFT.mp4");//读取视频video.open(0);//读取摄像头if (!video.i…

linux docker安装

一、Linux安装docker 1.1 前提 要求Linux内核(kernel) 版本大于等于3.8。(kernel version >3.8)。 查看当前系统内核版本 uname -a | awk {split($3,arr,"-");print arr[1]} 1.2 linux 安装docker Centos安装doc…

【数据结构与算法】7、队列(Queue)的实现【用栈实现队列】

目录 一、队列介绍二、使用 LinkedList 实现队列三、LeetCode:用【栈】实现队列(1) 老师讲之前我自己的实现(Correct)(2) 实现思路(3) 代码实现 四、jdk 的 Queue五、双端队列(Deque)六、循环队列(1) 分析(2) 入队(3) …

Linux--运行指令的本质

本质: ①找到它 which的作用就是找到它 ②运行它 示例: ①告诉系统要运行的指令,然后系统去查找它的路径并运行它 ②自己告诉系统自己要运行的路径,然后系统运行它 注意:a.out不能运行,而./a.out能运行…

MES是如何帮助企业提高生产效率的

大多数提高制造生产效率的系统都是从详细分析公司的制造流程和运营开始的。这样做的目的是是为了消除浪费的不增值的流程,将有价值的流程系统化,实现生产自动化并增强增值操作。 在自动化流程方面,实施制造执行系统(MES&#xff…

HTML5 游戏开发实战 | 俄罗斯方块

俄罗斯方块是一款风靡全球的电视游戏机和掌上游戏机游戏,它曾经造成的轰动与造成的经济价值可以说是游戏史上的一件大事。这款游戏看似简单但却变化无穷,游戏过程仅需要玩家将不断下落的各种形状的方块移动、翻转,如果某一行被方块充满了&…

发送邮箱验证码【spring boot】

⭐前言⭐ ※※※大家好!我是同学〖森〗,一名计算机爱好者,今天让我们进入学习模式。若有错误,请多多指教。更多有趣的代码请移步Gitee 👍 点赞 ⭐ 收藏 📝留言 都是我创作的最大的动力! 1. 思维…

Redis6之穿透、击穿、雪崩

大量的高并发的请求打在Redis上,但是发现Redis中并没有请求的数据,redis的命令率降低,所以这些请求就只能直接打在DB(数据库服务器)上,在大量的高并发的请求下就会导致DB直接卡死、宕机。 缓存穿透 当客户端…

一例Phorpiex僵尸网络样本分析

本文主要分析Phorpiex僵尸网络的一个变种,该样本通常NSIS打包,能够检测虚拟机和沙箱。病毒本体伪装为一个文件夹,通过U盘来传播,会隐藏系统中各盘符根目录下的文件夹,创建同名的lnk文件,诱导用户点击。 病…

TF卡/U盘系统备份

Jetson nano使用TF卡/U盘来装载系统,如果TF卡/U盘丢失或者损坏,那么Jetson nano上的数据都会丢失,所以一定要备份好TF卡/U盘。这篇文章可以帮你备份你的Jetson nano系统。主要内容为备份TF卡/U盘,制作Jetson nano系统镜像以及在需…

Java——《面试题——ElasticSearch篇》

目录 1、谈谈分词与倒排索引的原理 2、说说分段存储的思想 3、谈谈你对段合并的策略思想的认识 4、了解文本相似度 TF-IDF吗 5、能说说ElasticSearch 写索引的逻辑吗? 6、熟悉ElasticSearch 集群中搜索数据的过程吗? 7、了解ElasticSearch 深翻页的…

vsCode 创建新java项目(创建一个新java项目测试方法)

VSCODE环境配置-java之项目建立,非常适合刚准备使用VSCODE开发JAVA的人_vscode创建java项目_rainmenzhao的博客-CSDN博客 1 按 ctrl shift p 2 输入 create Java project 3 选 no build tools 4 选择 一个文件夹 存放 之后要 新建的文件 5 选完之后 自动返回主页…

获得Jolt 大奖的《持续交付》作者David Farley又一新作《现代软件工程》

戴维 法利 (David Farley) 是持续交付的先驱、思想领袖, 也是持续交付、 DevOps、 测试驱动开发和软件开发领域的专家。 从现代计算的早期开始,戴维曾担任过程序员、软件工程师、系统架构师和成功团 队的领导者,他掌握了计算机和软件开发的基…

ES基本操作(postman篇)

关系型数据库 -> Databases(库) -> Tables(表) -> Rows(行) -> Columns(列)。Elasticsearch -> Indeces(索引) -> Types(类型) -> Documents(文档) -> Fields(属性)。 需要注意的是:type的概念在es7.0之后已经删除了。 以下仅做刚入门学习…

矩阵对角线元素的和:揭秘数学之美,解密矩阵的隐秘密码

本篇博客会讲解力扣“1572. 矩阵对角线元素的和”的解题思路,这是题目链接。 本题的思路是:主对角线的下标满足i j,副对角线的下标满足i j size - 1,故只需要使用i遍历每一行,把(i, i)和(i, size - i - 1)的元素求和…

探索 Spring Boot 项目全过程

文章目录 🎇前言1.Spring Boot 所需环境2.Spring Boot 项目创建2.1 安装插件2.2 创建新项目2.3 项目属性配置2.4添加依赖2.4 修改项目名称2.5 添加框架支持2.6 目录介绍 3.判断Spring Boot 创建项目是否成功🎆总结 🎇前言 在 Java 这个圈子&…

1. Except

文章目录 Except前言Except 语法Except 使用举例结合其他关键字使用EXCEPT with BETWEEN operatorExcept with IN operatorEXCEPT with LIKE operator 文章参考 Except 前言 SQL中,EXCEPT 操作用于检索存在于第一个表中的唯一记录,而不是两个表中共有的…