import
tkinter as tk
from
tkinter
import
messagebox, filedialog
import
datetime
import
threading
import
time
import
os
import
sys
import
platform
from
playsound
import
playsound
import
ntplib
import
socket
def
sync_time():
try
:
client
=
ntplib.NTPClient()
response
=
client.request(
'pool.ntp.org'
)
network_time
=
datetime.datetime.fromtimestamp(response.tx_time)
if
platform.system()
=
=
'Windows'
:
os.system(f
'date {network_time:%Y-%m-%d}'
)
os.system(f
'time {network_time:%H:%M:%S}'
)
else
:
os.system(f
'sudo date -s "{network_time}"'
)
except
(ntplib.NTPException, socket.error):
return
False
return
True
class
AlarmManager:
def
__init__(
self
):
self
.alarms
=
[]
self
.running
=
True
self
.thread
=
threading.Thread(target
=
self
._check_alarms)
self
.thread.daemon
=
True
self
.thread.start()
def
_check_alarms(
self
):
while
self
.running:
now
=
datetime.datetime.now().strftime(
"%H:%M"
)
for
alarm
in
self
.alarms[:]:
if
alarm[
'time'
]
=
=
now
and
not
alarm[
'triggered'
]:
alarm[
'triggered'
]
=
True
self
._trigger_alarm(alarm)
time.sleep(
10
)
def
_trigger_alarm(
self
, alarm):
if
alarm[
'sound'
]:
threading.Thread(target
=
playsound, args
=
(alarm[
'sound'
],)).start()
messagebox.showinfo(
"闹钟提醒"
, f
"时间到!{alarm['time']}"
)
def
add_alarm(
self
, time_str, sound
=
None
):
self
.alarms.append({
'time'
: time_str,
'sound'
: sound,
'triggered'
:
False
})
def
remove_alarm(
self
, index):
if
0
<
=
index <
len
(
self
.alarms):
del
self
.alarms[index]
class
ClockApp(tk.Tk):
def
__init__(
self
):
super
().__init__()
self
.title(
"智能时钟工具"
)
self
.geometry(
"400x300"
)
self
.alarm_manager
=
AlarmManager()
self
.time_label
=
tk.Label(
self
, font
=
(
'Arial'
,
40
))
self
.time_label.pack(pady
=
20
)
self
.date_label
=
tk.Label(
self
, font
=
(
'Arial'
,
20
))
self
.date_label.pack()
self
.alarm_listbox
=
tk.Listbox(
self
, width
=
30
)
self
.alarm_listbox.pack(pady
=
10
)
btn_frame
=
tk.Frame(
self
)
btn_frame.pack(pady
=
10
)
self
.time_entry
=
tk.Entry(btn_frame, width
=
10
)
self
.time_entry.pack(side
=
tk.LEFT, padx
=
5
)
tk.Button(btn_frame, text
=
"添加闹钟"
, command
=
self
.add_alarm).pack(side
=
tk.LEFT, padx
=
5
)
tk.Button(btn_frame, text
=
"删除闹钟"
, command
=
self
.remove_alarm).pack(side
=
tk.LEFT, padx
=
5
)
tk.Button(btn_frame, text
=
"选择音乐"
, command
=
self
.select_music).pack(side
=
tk.LEFT, padx
=
5
)
self
.music_file
=
None
self
.update_time()
self
.attributes(
'-topmost'
,
True
)
def
update_time(
self
):
now
=
datetime.datetime.now()
self
.time_label.config(text
=
now.strftime(
"%H:%M:%S"
))
self
.date_label.config(text
=
now.strftime(
"%Y-%m-%d %A"
))
self
.after(
1000
,
self
.update_time)
def
add_alarm(
self
):
time_str
=
self
.time_entry.get()
try
:
datetime.datetime.strptime(time_str,
"%H:%M"
)
self
.alarm_manager.add_alarm(time_str,
self
.music_file)
self
.alarm_listbox.insert(tk.END, f
"{time_str} - {os.path.basename(self.music_file) if self.music_file else '无音乐'}"
)
except
ValueError:
messagebox.showerror(
"错误"
,
"时间格式应为 HH:MM"
)
def
remove_alarm(
self
):
selection
=
self
.alarm_listbox.curselection()
if
selection:
index
=
selection[
0
]
self
.alarm_manager.remove_alarm(index)
self
.alarm_listbox.delete(index)
def
select_music(
self
):
self
.music_file
=
filedialog.askopenfilename(
filetypes
=
[(
"音频文件"
,
"*.mp3 *.wav"
)]
)
def
set_autostart(enable
=
True
):
system
=
platform.system()
if
system
=
=
"Windows"
:
import
winreg
key
=
winreg.HKEY_CURRENT_USER
path
=
r
"Software\Microsoft\Windows\CurrentVersion\Run"
try
:
with winreg.OpenKey(key, path,
0
, winreg.KEY_WRITE) as regkey:
if
enable:
exe_path
=
os.path.abspath(sys.argv[
0
])
winreg.SetValueEx(regkey,
"SmartClock"
,
0
, winreg.REG_SZ, exe_path)
else
:
winreg.DeleteValue(regkey,
"SmartClock"
)
except
WindowsError:
pass
elif
system
=
=
"Linux"
:
autostart_dir
=
os.path.expanduser(
"~/.config/autostart"
)
desktop_file
=
os.path.join(autostart_dir,
"smartclock.desktop"
)
if
enable:
if
not
os.path.exists(autostart_dir):
os.makedirs(autostart_dir)
with
open
(desktop_file,
"w"
) as f:
f.write(f
)
else
:
if
os.path.exists(desktop_file):
os.remove(desktop_file)
if
__name__
=
=
"__main__"
:
if
not
sync_time():
messagebox.showwarning(
"警告"
,
"网络时间同步失败,使用本地时间"
)
try
:
set_autostart(enable
=
True
)
except
PermissionError:
messagebox.showwarning(
"警告"
,
"需要管理员权限设置开机自启"
)
app
=
ClockApp()
app.mainloop()