前言

使用Tkinter写一个简单的电子日历界面。


一、基本功能

  1. 能够显示当前日期与时间(年月日时分秒),与系统时间或网络时间自动同步、自动更新。
  2. 具有一般日历的 GUI 界面与功能
    ① 特殊显示“当天”,当前时间所在的天在日历中高亮显示;
    ② 默认显示本月的日历,但可以任意切换到其他年与月份;
    ③ 一键“回到今天”,在浏览其他月份时,可以一键回到当前日期所在的月份;
    ④ 点选某一天可以显示与“今天”相隔的天数;

先看完整代码:

import tkinter as tk
import requests
import time
import calendar
import ctypes

from tkinter import messagebox


class CalendarApp:
    def __init__(self, master):
        self.master = master
        self.master.title("电子日历系统")
        self.master.geometry("1000x1000")
        self.current_year = time.localtime().tm_year
        self.current_month = time.localtime().tm_mon
        self.current_day = time.localtime().tm_mday
        self.today = (self.current_year, self.current_month, self.current_day)
        self.create_widgets()

    def create_widgets(self):
        # 顶部时间显示
        self.time_label = tk.Label(self.master, text="", font=("Arial", 20))
        self.time_label.pack(pady=20)
        self.update_time()



        # 日历显示
        self.calendar_frame = tk.Frame(self.master)
        self.calendar_frame.pack(pady=20)
        self.create_calendar()


    def update_time(self):
        current_time = time.strftime("%Y年%m月%d日 %H:%M:%S", time.localtime())
        self.time_label.config(text=current_time)
        self.master.after(1000, self.update_time)


    def create_calendar(self):
        self.calendar_frame.destroy()
        self.calendar_frame = tk.Frame(self.master)
        self.calendar_frame.pack(pady=20)

        # 年份和月份选择
        year_var = tk.StringVar(value=str(self.current_year))
        year_label = tk.Label(self.calendar_frame, text="年份:")
        year_label.grid(row=0, column=0, padx=5)
        year_entry = tk.Entry(self.calendar_frame, width=6, textvariable=year_var)
        year_entry.grid(row=0, column=1, padx=5)

        month_var = tk.StringVar(value=str(self.current_month))
        month_label = tk.Label(self.calendar_frame, text="月份:")
        month_label.grid(row=0, column=2, padx=5)
        month_entry = tk.Entry(self.calendar_frame, width=4, textvariable=month_var)
        month_entry.grid(row=0, column=3, padx=5)

        # 回到今天按钮
        today_button = tk.Button(self.calendar_frame, text="回到今天", command=self.go_to_today)
        today_button.grid(row=0, column=4, padx=5)

        # 日历显示
        days = calendar.monthcalendar(int(year_var.get()), int(month_var.get()))
        weekday_names = ["一", "二", "三", "四", "五", "六", "日"]
        for i, name in enumerate(weekday_names):
            label = tk.Label(self.calendar_frame, text=name, font=("Arial", 16))
            label.grid(row=1, column=i, padx=5, pady=5)
        for i, week in enumerate(days):
            for j, day in enumerate(week):
                if day == 0:
                    continue
                button = tk.Button(self.calendar_frame, text=str(day), font=("Arial", 16), width=3, height=2)
                button.grid(row=i+2, column=j, padx=5, pady=5)
                if (int(year_var.get()), int(month_var.get()), day) == self.today:
                    button.config(bg="yellow")
                button.bind("<Button-1>", lambda event, day=day: self.show_days_diff(day))

    def go_to_today(self):
        self.current_year = self.today[0]
        self.current_month = self.today[1]
        self.create_calendar()

    def show_days_diff(self, day):
        days_diff = (time.mktime((self.current_year, self.current_month, day, 0, 0, 0, 0, 0, 0)) - 
                     time.mktime((self.today[0], self.today[1], self.today[2], 0, 0, 0, 0, 0, 0))) // (24 * 60 * 60)
        tk.messagebox.showinfo("相隔天数", f"今天与{self.current_year}{self.current_month}{day}日相隔{days_diff}天")

if __name__ == "__main__":
    
    # 创建窗口:root是自己定义的窗口
    root = tk.Tk()
    
    # 界面优化---------------------------------
    # 调用api设置成由应用程序缩放
    ctypes.windll.shcore.SetProcessDpiAwareness(1)
    # 调用api获得当前的缩放因子
    ScaleFactor=ctypes.windll.shcore.GetScaleFactorForDevice(0)
    # 设置缩放因子
    root.tk.call('tk', 'scaling', ScaleFactor/75)
    #--------------------------------------------
    app = CalendarApp(root)
    root.mainloop()

  • 在上述代码中,我们使用了 tkinter 库创建 GUI 界面,使用 time 库获取当前时间,使用 calendar 库获取日历信息。
  • 在界面中,我们显示了当前时间。可以通过年份和月份选择来切换日历的显示,点击“回到今天”按钮可以回到当前日期所在的月份,点击某一天可以显示与“今天”相隔的天数。同时,我们也可以根据自己的需求对界面进行美化和功能的扩展。

二、效果展示

总结

Tkinter用来UI展示是一个不错的选择,最近也在学习中。