PySimpleGUI中是否有Tkinter.after()等效方法实现元素定时延迟更新?
PySimpleGUI实现每日更新日出日落+秒级时钟
针对你要在PySimpleGUI中同时实现秒级更新时钟、每日仅更新一次日出日落的需求,下面是对原代码的优化修复方案:
原代码存在的问题
- 日出日落更新逻辑错误:原判断
datetime.datetime.now().hour >9会导致程序启动时若在9点前就完全不执行更新,也不会触发后续的定时任务 - 定时周期错误:
after()参数是毫秒,原代码写1*60*60只设置了1小时,而非24小时 - 模块重复导入:
sunrise_sunset()函数内部重复导入模块,影响运行效率 - 异常处理bug:直接写入Exception对象到日志会报错,需要转为字符串
修复后的完整代码
import time import PySimpleGUI as sg import datetime from datetime import date from suntime import Sun from geopy.geocoders import Nominatim sg.theme_background_color('#3d5c5c') clockFont = ('Fira Code', 18) br1 = {'font': ('Fira Code', 18,'bold')} def sunrise_sunset(place="my_location"): # 替换为你的位置 geolocator = Nominatim(user_agent="geoapiExercises") location = geolocator.geocode(place) latitude = location.latitude longitude = location.longitude sun = Sun(latitude, longitude) today = date.today() sun_rise = sun.get_local_sunrise_time(today) sun_dusk = sun.get_local_sunset_time(today) return (sun_rise.strftime('%H:%M'), sun_dusk.strftime('%H:%M')) layout = [ [ sg.Text("Sunrise", **br1, key='-SUNRISE-', size=(13,1), text_color='black',background_color="#00ced1"), sg.InputText("", size=(6, 1), **br1, key='-ALBA-', text_color='black',background_color='#00ced1'), sg.Text("", key='-CLK-', font=clockFont, size=(13,1), background_color="#65000B"), sg.Text("Sunset", key='-SUNSET-', **br1, size=(13,1), text_color='black',background_color="#EEAF61"), sg.InputText("", size=(6, 1), **br1, key='-TRAMONTO-',text_color='black', background_color="#EEAF61"), ]] window = sg.Window('Run Scripts', layout, finalize=True) def update_sunrise_sunset(): # 立即更新当日日出日落 sunrise, sunset = sunrise_sunset() window['-ALBA-'].update(sunrise) window['-TRAMONTO-'].update(sunset) # 设置24小时后再次执行(单位:毫秒) window.TKroot.after(24*60*60*1000, update_sunrise_sunset) # 程序启动时先执行一次更新 update_sunrise_sunset() while True: event, values = window.read(timeout=100) try: if event == sg.TIMEOUT_EVENT: currentTime = time.strftime("%H:%M:%S") window['-CLK-'].update(currentTime) except Exception as e: with open('Run_Scripts_ERRORS_LOG', "a", encoding='utf-8') as f: f.write(f"{datetime.datetime.now()}: {str(e)}\n") if event == sg.WIN_CLOSED: break window.close()
关键优化点说明
- 把
sunrise_sunset()内部的模块导入移到顶部,避免重复导入浪费资源 - 移除错误的小时判断逻辑,程序启动时立即获取当日日出日落数据,之后每24小时自动更新
- 修正
after()的参数为24*60*60*1000(即24小时的毫秒数),确保每日仅更新一次 - 修复异常日志的写入逻辑,添加时间戳并将异常转为字符串,避免报错
- 循环结束后添加
window.close(),确保资源正常释放
内容的提问来源于stack exchange,提问作者LetzerWille
相关产品推荐
相关产品推荐

