|
|
|
|
import tkinter as tk
|
|
|
|
|
from PIL import Image, ImageTk
|
|
|
|
|
import time
|
|
|
|
|
import math
|
|
|
|
|
import pygame
|
|
|
|
|
from pygame.locals import *
|
|
|
|
|
import sys
|
|
|
|
|
import os
|
|
|
|
|
import win32gui
|
|
|
|
|
import win32con
|
|
|
|
|
|
|
|
|
|
# 创建一个变量,用于记录当前是否显示数字时间
|
|
|
|
|
show_digital_time = False
|
|
|
|
|
|
|
|
|
|
# 定义全局范围内的变量
|
|
|
|
|
# 数字列表
|
|
|
|
|
hours_numbers = list(range(24))
|
|
|
|
|
minutes_numbers = list(range(60))
|
|
|
|
|
# 当前显示的小时和分钟索引
|
|
|
|
|
hour_index = minutes_index = 0
|
|
|
|
|
|
|
|
|
|
def draw_clock():
|
|
|
|
|
# 清除画布
|
|
|
|
|
canvas.delete('all')
|
|
|
|
|
|
|
|
|
|
if show_digital_time:
|
|
|
|
|
# 显示数字时间
|
|
|
|
|
current_time = time.strftime('%H:%M:%S', time.localtime())
|
|
|
|
|
canvas.create_text(center_x, center_y, text=current_time, font=("Arial", 30))
|
|
|
|
|
|
|
|
|
|
else:
|
|
|
|
|
# 绘制表盘
|
|
|
|
|
canvas.create_oval(center_x - second_length, center_y - second_length, center_x + second_length,
|
|
|
|
|
center_y + second_length)
|
|
|
|
|
|
|
|
|
|
# 绘制小时刻度和数字
|
|
|
|
|
for i in range(12):
|
|
|
|
|
angle = math.pi / 6 * (i - 3)
|
|
|
|
|
start_x = center_x + (second_length - 10) * math.cos(angle)
|
|
|
|
|
start_y = center_y + (second_length - 10) * math.sin(angle)
|
|
|
|
|
end_x = center_x + second_length * math.cos(angle)
|
|
|
|
|
end_y = center_y + second_length * math.sin(angle)
|
|
|
|
|
canvas.create_line(start_x, start_y, end_x, end_y, width=3)
|
|
|
|
|
|
|
|
|
|
# 计算数字的位置
|
|
|
|
|
number_x = center_x + (second_length - 20) * math.cos(angle)
|
|
|
|
|
number_y = center_y + (second_length - 20) * math.sin(angle)
|
|
|
|
|
|
|
|
|
|
# 绘制数字
|
|
|
|
|
canvas.create_text(number_x, number_y, text=str(i + 1), font=("Arial", 15))
|
|
|
|
|
|
|
|
|
|
# 绘制分钟刻度
|
|
|
|
|
for i in range(60):
|
|
|
|
|
angle = math.pi / 30 * (i - 15)
|
|
|
|
|
start_x = center_x + (second_length - 5) * math.cos(angle)
|
|
|
|
|
start_y = center_y + (second_length - 5) * math.sin(angle)
|
|
|
|
|
end_x = center_x + second_length * math.cos(angle)
|
|
|
|
|
end_y = center_y + second_length * math.sin(angle)
|
|
|
|
|
canvas.create_line(start_x, start_y, end_x, end_y)
|
|
|
|
|
|
|
|
|
|
# 获取当前时间
|
|
|
|
|
current_time = time.localtime()
|
|
|
|
|
hours = current_time.tm_hour
|
|
|
|
|
minutes = current_time.tm_min
|
|
|
|
|
seconds = current_time.tm_sec
|
|
|
|
|
|
|
|
|
|
# 绘制时针
|
|
|
|
|
hour_angle = math.pi / 6 * (hours - 3)
|
|
|
|
|
hour_x = center_x + hour_length * math.cos(hour_angle)
|
|
|
|
|
hour_y = center_y + hour_length * math.sin(hour_angle)
|
|
|
|
|
canvas.create_line(center_x, center_y, hour_x, hour_y, width=6, fill='black')
|
|
|
|
|
|
|
|
|
|
# 绘制分针
|
|
|
|
|
minute_angle = math.pi / 30 * (minutes - 15)
|
|
|
|
|
minute_x = center_x + minute_length * math.cos(minute_angle)
|
|
|
|
|
minute_y = center_y + minute_length * math.sin(minute_angle)
|
|
|
|
|
canvas.create_line(center_x, center_y, minute_x, minute_y, width=4, fill='blue')
|
|
|
|
|
|
|
|
|
|
# 绘制秒针
|
|
|
|
|
second_angle = math.pi / 30 * (seconds - 15)
|
|
|
|
|
second_x = center_x + second_length * math.cos(second_angle)
|
|
|
|
|
second_y = center_y + second_length * math.sin(second_angle)
|
|
|
|
|
canvas.create_line(center_x, center_y, second_x, second_y, fill='red')
|
|
|
|
|
|
|
|
|
|
# 每1000毫秒更新一次
|
|
|
|
|
window.after(1000, draw_clock)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
def toggle_time_display(event):
|
|
|
|
|
global show_digital_time
|
|
|
|
|
show_digital_time = not show_digital_time
|
|
|
|
|
draw_clock()
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
# 创建窗口
|
|
|
|
|
window = tk.Tk()
|
|
|
|
|
window.title('时钟')
|
|
|
|
|
# 设置窗口不可改变大小
|
|
|
|
|
window.resizable(False, False)
|
|
|
|
|
|
|
|
|
|
# 设置主窗口位置
|
|
|
|
|
window.geometry('+400+50')
|
|
|
|
|
|
|
|
|
|
# 设置窗口背景颜色
|
|
|
|
|
window.configure(background='white')
|
|
|
|
|
add_button_image = Image.open('xxx.png')
|
|
|
|
|
add_button_image = add_button_image.convert('RGBA')
|
|
|
|
|
add_button_image = ImageTk.PhotoImage(add_button_image)
|
|
|
|
|
'''
|
|
|
|
|
from tkinter import END, Button, Toplevel, Listbox
|
|
|
|
|
|
|
|
|
|
# 创建一个列表,用于记录设置的闹钟
|
|
|
|
|
alarms = []
|
|
|
|
|
# 创建一个列表框,用于显示设置的闹钟
|
|
|
|
|
alarm_listbox = Listbox(window)
|
|
|
|
|
alarm_listbox.pack(side='bottom')
|
|
|
|
|
'''
|
|
|
|
|
|
|
|
|
|
def set_alarm():
|
|
|
|
|
|
|
|
|
|
def set_window_position(hwnd, x, y):
|
|
|
|
|
win32gui.SetWindowPos(hwnd, win32con.HWND_TOP, x, y, 0, 0, win32con.SWP_NOSIZE)
|
|
|
|
|
|
|
|
|
|
# 定义全局范围内的变量
|
|
|
|
|
# 数字列表
|
|
|
|
|
hours_numbers = list(range(24))
|
|
|
|
|
minutes_numbers = list(range(60))
|
|
|
|
|
# 当前显示的小时、分钟和秒钟索引
|
|
|
|
|
hour_index = minutes_index = 0
|
|
|
|
|
|
|
|
|
|
# 初始化pygame
|
|
|
|
|
pygame.init()
|
|
|
|
|
|
|
|
|
|
# 设置窗口大小,移除窗口的标题栏和边框,包括关闭按钮。
|
|
|
|
|
screen = pygame.display.set_mode((380, 300), pygame.NOFRAME)
|
|
|
|
|
|
|
|
|
|
# 获取pygame窗口的hwnd
|
|
|
|
|
hwnd = pygame.display.get_wm_info()["window"]
|
|
|
|
|
|
|
|
|
|
# 设置窗口位置
|
|
|
|
|
set_window_position(hwnd, 410, 400)
|
|
|
|
|
# 设置主窗口位置
|
|
|
|
|
main_window_x = 400
|
|
|
|
|
main_window_y = 50
|
|
|
|
|
window.geometry(f'+{main_window_x}+{main_window_y}')
|
|
|
|
|
|
|
|
|
|
# 设置Pygame窗口位置
|
|
|
|
|
pygame_window_x = main_window_x + 10 # 自定义偏移
|
|
|
|
|
pygame_window_y = main_window_y + 400 # 自定义偏移
|
|
|
|
|
set_window_position(hwnd, pygame_window_x, pygame_window_y)
|
|
|
|
|
|
|
|
|
|
# 字体和颜色设置
|
|
|
|
|
font = pygame.font.SysFont('Arial', 72)
|
|
|
|
|
text_color = (0, 0, 0)
|
|
|
|
|
background_color = (255, 255, 255)
|
|
|
|
|
|
|
|
|
|
# 滚动区域定义
|
|
|
|
|
hour_scroll_area = pygame.Rect(10, 20, 200, 100) # 修改x坐标和宽度
|
|
|
|
|
minute_scroll_area = pygame.Rect(150, 20, 200, 100) # 修改x坐标和宽度
|
|
|
|
|
|
|
|
|
|
# 创建一个 "确认" 按钮
|
|
|
|
|
add_button = pygame.Rect(170, 180, 50, 50)
|
|
|
|
|
# 创建一个 "停止" 按钮
|
|
|
|
|
stop_button = pygame.Rect(250, 90, 120, 100)
|
|
|
|
|
|
|
|
|
|
# 设置音乐文件路径
|
|
|
|
|
music_file = 'alarm.wav'
|
|
|
|
|
|
|
|
|
|
# 鼠标操作相关变量
|
|
|
|
|
scrolling_hour = scrolling_minute = False
|
|
|
|
|
scroll_start_time = scroll_end_time = 0.0
|
|
|
|
|
scroll_start_index_hour = scroll_start_index_minute = 0
|
|
|
|
|
scroll_target_hour = scroll_target_minute = 0
|
|
|
|
|
scroll_speed = 5 # 单位时间内滚动的索引数量
|
|
|
|
|
friction = 0.9 # 摩擦系数,用于模拟滚动阻力
|
|
|
|
|
|
|
|
|
|
# 创建一个clock实例用于控制帧率
|
|
|
|
|
clock = pygame.time.Clock()
|
|
|
|
|
|
|
|
|
|
# 定义绘制数字的函数
|
|
|
|
|
def draw_number(screen, number, x, y):
|
|
|
|
|
text_surface = font.render(str(number), True, text_color)
|
|
|
|
|
screen.blit(text_surface, (x, y))
|
|
|
|
|
window.update()
|
|
|
|
|
# 新窗口相关变量
|
|
|
|
|
new_window = None
|
|
|
|
|
new_window_open = False
|
|
|
|
|
|
|
|
|
|
# 添加一个标志来记录音乐是否已经开始播放
|
|
|
|
|
music_started = False
|
|
|
|
|
|
|
|
|
|
# 添加一个标志来记录按钮的状态,True 表示开,False 表示关
|
|
|
|
|
button_open = True
|
|
|
|
|
|
|
|
|
|
# 添加一个标志来记录是否需要播放音乐
|
|
|
|
|
need_play_music = False
|
|
|
|
|
|
|
|
|
|
# 在主循环开始时初始化 stop_button 和 stop_button_image
|
|
|
|
|
stop_button = pygame.Rect(265, 95, 120, 100) # 设置这个矩形的位置和大小
|
|
|
|
|
stop_button_image = pygame.image.load('open.jpg') # 加载按钮图片
|
|
|
|
|
|
|
|
|
|
# 主循环
|
|
|
|
|
while True:
|
|
|
|
|
# 获取当前时间
|
|
|
|
|
current_time = time.time()
|
|
|
|
|
|
|
|
|
|
# 处理事件
|
|
|
|
|
for event in pygame.event.get():
|
|
|
|
|
if event.type == pygame.QUIT:
|
|
|
|
|
pygame.quit()
|
|
|
|
|
sys.exit()
|
|
|
|
|
|
|
|
|
|
elif event.type == MOUSEBUTTONDOWN or event.type == MOUSEWHEEL: # 处理鼠标点击和滚轮事件
|
|
|
|
|
mouse_pos = pygame.mouse.get_pos()
|
|
|
|
|
if hour_scroll_area.collidepoint(mouse_pos):
|
|
|
|
|
if event.type == MOUSEBUTTONDOWN:
|
|
|
|
|
if event.button == 1: # 鼠标左键
|
|
|
|
|
hour_index = (hour_index + 1) % len(hours_numbers)
|
|
|
|
|
elif event.button == 3: # 鼠标右键
|
|
|
|
|
hour_index = (hour_index - 1) % len(hours_numbers)
|
|
|
|
|
elif event.type == MOUSEWHEEL: # 鼠标滚轮滚动
|
|
|
|
|
if event.y > 0: # 滚轮向上滚动
|
|
|
|
|
hour_index = (hour_index - 1) % len(hours_numbers)
|
|
|
|
|
elif event.y < 0: # 滚轮向下滚动
|
|
|
|
|
hour_index = (hour_index + 1) % len(hours_numbers)
|
|
|
|
|
elif minute_scroll_area.collidepoint(mouse_pos):
|
|
|
|
|
if event.type == MOUSEBUTTONDOWN:
|
|
|
|
|
if event.button == 1: # 鼠标左键
|
|
|
|
|
minutes_index = (minutes_index + 1) % len(minutes_numbers)
|
|
|
|
|
elif event.button == 3: # 鼠标右键
|
|
|
|
|
minutes_index = (minutes_index - 1) % len(minutes_numbers)
|
|
|
|
|
elif event.type == MOUSEWHEEL: # 鼠标滚轮滚动
|
|
|
|
|
if event.y > 0: # 滚轮向上滚动
|
|
|
|
|
minutes_index = (minutes_index - 1) % len(minutes_numbers)
|
|
|
|
|
elif event.y < 0: # 滚轮向下滚动
|
|
|
|
|
minutes_index = (minutes_index + 1) % len(minutes_numbers)
|
|
|
|
|
|
|
|
|
|
elif event.type == pygame.MOUSEBUTTONDOWN:
|
|
|
|
|
if add_button.collidepoint(event.pos):
|
|
|
|
|
|
|
|
|
|
# 创建新的表面并显示设置的时间
|
|
|
|
|
new_window = pygame.Surface((400, 300))
|
|
|
|
|
new_window.fill(background_color)
|
|
|
|
|
|
|
|
|
|
draw_number(new_window, f"{hour_index:02d}:{minutes_index:02d}", 80, 100)
|
|
|
|
|
|
|
|
|
|
# 加载停止按钮图片
|
|
|
|
|
stop_button_image = pygame.image.load('open.jpg' if button_open else 'close.jpg')
|
|
|
|
|
|
|
|
|
|
# 绘制停止按钮图片
|
|
|
|
|
new_window.blit(stop_button_image, stop_button.topleft)
|
|
|
|
|
new_window_open = True
|
|
|
|
|
|
|
|
|
|
continue # 跳过后面的鼠标事件处理逻辑
|
|
|
|
|
elif pygame.Rect(stop_button.topleft, stop_button_image.get_size()).collidepoint(event.pos) and new_window_open:
|
|
|
|
|
# 根据按钮的状态来开始或停止音乐播放
|
|
|
|
|
if button_open:
|
|
|
|
|
pygame.mixer.music.stop()
|
|
|
|
|
need_play_music = False
|
|
|
|
|
else:
|
|
|
|
|
need_play_music = True
|
|
|
|
|
|
|
|
|
|
# 切换按钮的状态
|
|
|
|
|
button_open = not button_open
|
|
|
|
|
|
|
|
|
|
# 加载新的按钮图片
|
|
|
|
|
stop_button_image = pygame.image.load('open.jpg' if button_open else 'close.jpg')
|
|
|
|
|
|
|
|
|
|
# 绘制新的按钮图片
|
|
|
|
|
new_window.blit(stop_button_image, stop_button.topleft)
|
|
|
|
|
|
|
|
|
|
# 在主循环中检查是否需要播放音乐
|
|
|
|
|
if need_play_music and not pygame.mixer.music.get_busy():
|
|
|
|
|
current_time = time.strftime("%H:%M", time.localtime())
|
|
|
|
|
set_time = f"{hour_index}:{minutes_index}"
|
|
|
|
|
if set_time <= current_time < f"{hour_index}:{(minutes_index + 1) % 60:02d}":
|
|
|
|
|
pygame.mixer.music.load(music_file)
|
|
|
|
|
pygame.mixer.music.play()
|
|
|
|
|
|
|
|
|
|
# 平滑滚动逻辑
|
|
|
|
|
if scrolling_hour or scrolling_minute:
|
|
|
|
|
elapsed_time = current_time - scroll_start_time
|
|
|
|
|
|
|
|
|
|
# 计算目标索引(这里假设滚轮宽度与索引数成正比)
|
|
|
|
|
scroll_direction_hour = 1
|
|
|
|
|
target_hour_diff = (scroll_target_hour - hour_scroll_area.x) / hour_scroll_area.w * len(hours_numbers)
|
|
|
|
|
target_minute_diff = (scroll_target_minute - minute_scroll_area.x) / minute_scroll_area.w * len(
|
|
|
|
|
minutes_numbers)
|
|
|
|
|
|
|
|
|
|
# 线性插值计算当前索引
|
|
|
|
|
scroll_direction_minute = 1 # Initialize scroll_direction_minute
|
|
|
|
|
hour_interpolated_index = scroll_start_index_hour + scroll_speed * elapsed_time * scroll_direction_hour
|
|
|
|
|
minute_interpolated_index = scroll_start_index_minute + scroll_speed * elapsed_time * scroll_direction_minute
|
|
|
|
|
|
|
|
|
|
if not scrolling_hour:
|
|
|
|
|
friction_time = current_time - scroll_end_time
|
|
|
|
|
hour_interpolated_index *= pow(friction, friction_time)
|
|
|
|
|
if abs(hour_interpolated_index - target_hour_diff) < 1:
|
|
|
|
|
hour_index = int(target_hour_diff) % len(hours_numbers)
|
|
|
|
|
else:
|
|
|
|
|
hour_index = int(hour_interpolated_index) % len(hours_numbers)
|
|
|
|
|
|
|
|
|
|
if not scrolling_minute:
|
|
|
|
|
friction_time = current_time - scroll_end_time
|
|
|
|
|
minute_interpolated_index *= pow(friction, friction_time)
|
|
|
|
|
if abs(minute_interpolated_index - target_minute_diff) < 1:
|
|
|
|
|
minutes_index = int(target_minute_diff) % len(minutes_numbers)
|
|
|
|
|
else:
|
|
|
|
|
minutes_index = int(minute_interpolated_index) % len(minutes_numbers)
|
|
|
|
|
|
|
|
|
|
# 清除屏幕
|
|
|
|
|
screen.fill(background_color)
|
|
|
|
|
|
|
|
|
|
# 绘制数字
|
|
|
|
|
draw_number(screen, f"{hour_index:02d} : {minutes_index:02d}", hour_scroll_area.centerx, hour_scroll_area.centery)
|
|
|
|
|
|
|
|
|
|
# 加载按钮图片
|
|
|
|
|
button_image = pygame.image.load('button1.png')
|
|
|
|
|
|
|
|
|
|
# 绘制按钮图片
|
|
|
|
|
screen.blit(button_image, add_button.topleft)
|
|
|
|
|
|
|
|
|
|
# 如果新窗口打开,绘制新窗口
|
|
|
|
|
if new_window_open:
|
|
|
|
|
screen.blit(new_window, (0, 0))
|
|
|
|
|
# 到达设置的时间
|
|
|
|
|
current_time = time.strftime("%H:%M", time.localtime())
|
|
|
|
|
set_time = f"{hour_index}:{minutes_index}"
|
|
|
|
|
if set_time <= current_time < f"{hour_index}:{(minutes_index + 1) % 60:02d}":
|
|
|
|
|
# 只有当音乐还没有开始播放时,才加载和播放音乐
|
|
|
|
|
if not music_started:
|
|
|
|
|
pygame.mixer.music.load(music_file)
|
|
|
|
|
pygame.mixer.music.play()
|
|
|
|
|
music_started = True
|
|
|
|
|
# 更新屏幕并限制帧率
|
|
|
|
|
pygame.display.update()
|
|
|
|
|
clock.tick(60)
|
|
|
|
|
# 在 set_alarm 函数的 while True 主循环中添加以下内容
|
|
|
|
|
window.update()
|
|
|
|
|
|
|
|
|
|
# 设置主窗口的大小
|
|
|
|
|
window.geometry('400x800')
|
|
|
|
|
|
|
|
|
|
# 创建画布
|
|
|
|
|
canvas = tk.Canvas(window, width=400, height=800, bg='white')
|
|
|
|
|
canvas.pack()
|
|
|
|
|
# 创建一个按钮,用户点击这个按钮来打开设置闹钟的弹出窗口
|
|
|
|
|
#add_alarm_button = Button(window, text="+", command=set_alarm,bg='black', fg="white")
|
|
|
|
|
#add_alarm_button.place(x=200, y=700, anchor="center")
|
|
|
|
|
add_alarm_button = tk.Button(window, image=add_button_image, command=set_alarm, borderwidth=0, highlightthickness=0)
|
|
|
|
|
add_alarm_button.place(x=200, y=700, anchor="center")
|
|
|
|
|
# 定义时钟的参数
|
|
|
|
|
center_x = 200
|
|
|
|
|
center_y = 200
|
|
|
|
|
hour_length = 60
|
|
|
|
|
minute_length = 90
|
|
|
|
|
second_length = 100
|
|
|
|
|
|
|
|
|
|
# 绑定鼠标点击事件
|
|
|
|
|
canvas.bind("<Button-1>", toggle_time_display)
|
|
|
|
|
|
|
|
|
|
# 初始绘制表盘
|
|
|
|
|
draw_clock()
|
|
|
|
|
|
|
|
|
|
# 启动主循环
|
|
|
|
|
window.mainloop()
|