如何在CustomTkinter窗口中实现实时更新的时钟?
解决CustomTkinter实时时钟更新问题
你需要在CustomTkinter窗口中实现实时更新的时钟,当前代码仅能显示一次时间,无法自动刷新。以下是修改后的完整代码,实现日期和时间的实时更新:
from configparser import ConfigParser import sys from tkinter.messagebox import askyesno import customtkinter import datetime from datetime import datetime, timedelta import subprocess customtkinter.set_appearance_mode("System") # 模式: "System" (默认), "Dark", "Light" customtkinter.set_default_color_theme("blue") # 主题: "blue" (默认), "green", "dark-blue" normal_text_color = "gray10" disabled_text_color = "light slate gray" alert_color = "red" start_color = "green" manual_color = "blue" option_color1 = "purple3" option_color2 = "purple1" class App(customtkinter.CTk): def __init__(self): super().__init__() global normal_text_color global disabled_text_color global alert_color global start_color global manual_color global option_color1 global option_color2 r = 0 c = 0 stick = "" padderx = 0 # configure window self.title("test") self.geometry(f"{750}x{385}") # configure grid layout (4x4) self.grid_columnconfigure(1, weight=1) self.grid_columnconfigure((2, 3), weight=0) self.grid_rowconfigure((0, 1, 2, 5), weight=1) # create sidebar frame with widgets self.sidebar_frame = customtkinter.CTkFrame(self, width=140, corner_radius=0) self.sidebar_frame.grid(row=0, column=0, rowspan=9, sticky="nsew") self.sidebar_frame.grid_rowconfigure(9, weight=1) self.logo_label = customtkinter.CTkLabel(self.sidebar_frame, text="Controls", font=customtkinter.CTkFont(size=20, weight="bold")) self.logo_label.grid(row=0, column=0, padx=20, pady=(20, 10)) self.sidebar_button_1 = customtkinter.CTkButton(self.sidebar_frame, command=lambda: self.sidebar_button_event(1)) self.sidebar_button_1.grid(row=1, column=0, padx=20, pady=10) self.sidebar_button_2 = customtkinter.CTkButton(self.sidebar_frame, command=lambda: self.sidebar_button_event(2)) self.sidebar_button_2.grid(row=2, column=0, padx=20, pady=10) self.logo_label = customtkinter.CTkLabel(self.sidebar_frame, text="Options", font=customtkinter.CTkFont(size=20, weight="bold")) self.logo_label.grid(row=3, column=0, padx=20, pady=0) self.sidebar_button_3 = customtkinter.CTkButton(self.sidebar_frame, command=lambda: self.sidebar_button_event(3)) self.sidebar_button_3.grid(row=4, column=0, padx=20, pady=20) self.sidebar_button_4 = customtkinter.CTkButton(self.sidebar_frame, command=lambda: self.sidebar_button_event(4)) self.sidebar_button_4.grid(row=5, column=0, padx=20, pady=20) self.sidebar_button_5 = customtkinter.CTkButton(self.sidebar_frame, command=lambda: self.sidebar_button_event(5)) self.sidebar_button_5.grid(row=6, column=0, padx=20, pady=10) # create current_view for operations self.current_view = customtkinter.CTkFrame(self, width=100, fg_color="transparent") self.current_view.grid(row=0, column=1, rowspan=9, sticky="nsew") self.current_view.grid_columnconfigure((0, 1, 2, 3), weight=1) self.current_view.grid_rowconfigure(5, weight=1) # Show current operation self.current_label = customtkinter.CTkLabel(self.current_view, text="Current Operations", font=customtkinter.CTkFont(size=20, weight="bold")) self.current_label.grid(row=0, column=0, sticky="e", padx=20, pady=(20, 10)) # 初始化时钟标签(关键:提前创建标签,后续仅更新文本) self.date_label = customtkinter.CTkLabel(self.current_view, font=customtkinter.CTkFont(size=20, weight="bold")) self.date_label.grid(row=0, column=2, sticky="w", padx=20, pady=(0, 0)) self.time_label = customtkinter.CTkLabel(self.current_view, font=customtkinter.CTkFont(size=20, weight="bold")) self.time_label.grid(row=2, column=2, sticky="w", padx=20, pady=(0, 0)) # set operation labels self.operations() self.operation_values() # create feeding log textbox font=('Courier', 14) self.log_view = customtkinter.CTkTextbox(self, font=font, width=100) self.log_view.grid(row=8, column=1, padx=(20, 10), pady=(20, 10), sticky="nsew") self.log_view.tag_config("normal", foreground=normal_text_color) self.log_view.tag_config("start", foreground=start_color) self.log_view.tag_config("warn", foreground=alert_color) self.log_view.tag_config("disable", foreground=disabled_text_color) self.log_view.tag_config("manual", foreground=manual_color) self.log_view.tag_config("option1", foreground=option_color1) self.log_view.tag_config("option2", foreground=option_color2) # Configure the button names self.sidebar_button_1.configure(text="A") self.sidebar_button_2.configure(text="B") self.sidebar_button_3.configure(text="C") self.sidebar_button_4.configure(text="D") self.sidebar_button_4.configure(state="disabled") self.sidebar_button_5.configure(text="Quit") # 启动时钟更新 self.update_clock() # sets the operation type label only def operations(self): global normal_text_color global disabled_text_color global alert_color global start_color global manual_color # set Auto Feed label r = 1 c = 0 stick = "e" padderx = 20 current_text_color = normal_text_color text_text = "Auto:" self.update_labels(current_text_color, text_text, r, c, stick, padderx ) # next Feeding r += 1 current_text_color = normal_text_color text_text = "Begin Next:" self.update_labels(current_text_color, text_text, r, c, stick, padderx ) # hourly feeding r += 1 current_text_color = normal_text_color text_text = "Hourly:" self.update_labels(current_text_color, text_text, r, c, stick, padderx ) # how many feeding times per day. r += 1 current_text_color = normal_text_color text_text = "Per Day:" self.update_labels(current_text_color, text_text, r, c, stick, padderx ) # sets the operation type value only def operation_values(self): global normal_text_color global disabled_text_color global alert_color global start_color global manual_color r = 1 c = 1 stick = "w" padderx = 0 # auto feed text_text = "On " current_text_color = start_color self.update_labels(current_text_color, text_text, r, c, stick, padderx) # when is the next feeding? r += 1 text_text = "5:35 PM" current_text_color = start_color self.update_labels(current_text_color, text_text, r, c, stick, padderx ) # hourly feeding r += 1 text_text = "Off " current_text_color = alert_color self.update_labels(current_text_color, text_text, r, c, stick, padderx ) # if auto_feed is on, and hourly_feed is off, then display the number of times per day fed r += 1 text_text = "Off" current_text_color = alert_color self.update_labels(current_text_color, text_text, r, c, stick, padderx ) # updates a label. def update_labels(self, set_text_color, set_text, r, c, stick, pad_it ): self.current_label = customtkinter.CTkLabel(self.current_view, text_color=set_text_color, text=set_text, font=customtkinter.CTkFont(size=20, weight="bold")) self.current_label.grid(row=r, column=c, padx=pad_it, sticky=stick) # Handle the buttons def sidebar_button_event(self, buttonNum): if buttonNum == 5: sys.exit(0) # 更新时钟文本 def update_clock(self): now = datetime.now() # 更新日期标签 self.date_label.configure(text=now.strftime("%m/%d/%Y")) # 更新时间标签 self.time_label.configure(text=now.strftime("%-I:%M %p")) # 每隔1000毫秒(1秒)调用一次自身,实现循环更新 self.after(1000, self.update_clock) if __name__ == "__main__": app = App() app.mainloop()
关键修改说明
- 初始化时钟标签:在
__init__方法中提前创建date_label和time_label,避免每次更新都新建组件,造成界面冗余。 - 修改更新逻辑:将原
clock方法改为update_clock,仅更新已有标签的文本内容,而非重新创建标签。 - 定时触发更新:使用Tkinter(CustomTkinter基于Tkinter)的
after方法,每隔1秒调用一次update_clock,实现实时刷新。
内容的提问来源于stack exchange,提问作者Greg W
相关产品推荐
相关产品推荐

