使用python语言的tkinter、math、datetime模块编写的精美夜光模拟时钟,右键可以放大、缩小、关闭

使用python语言的tkinter、math、datetime模块编写的精美夜光模拟时钟,右键可以放大、缩小、关闭

效果图如下:

代码如下:

import tkinter as tk
from math import pi, sin, cos
from datetime import datetime

class AnalogClock:
    def __init__(self, master):
        self.master = master
        self.master.overrideredirect(True)  # 去掉窗口的标题栏和默认按钮
        self.master.geometry("400x400")  # 设置初始窗口大小
        self.master.resizable(True, True)  # 允许窗口调整大小

        # 创建右键菜单
        self.context_menu = tk.Menu(self.master, tearoff=0)
        self.context_menu.add_***mand(label="放大", ***mand=self.zoom_in)
        self.context_menu.add_***mand(label="缩小", ***mand=self.zoom_out)
        self.context_menu.add_***mand(label="关闭", ***mand=self.close_window)

        # 绑定右键菜单事件
        self.master.bind("<Button-3>", self.show_context_menu)

        # 绑定窗口大小变化事件
        self.master.bind("<Configure>", self.on_resize)

        # 绑定鼠标事件以实现窗口拖动
        self.master.bind("<Button-1>", self.start_drag)  # 鼠标左键按下
        self.master.bind("<B1-Motion>", self.drag_window)  # 鼠标左键拖动
        self.master.bind("<ButtonRelease-1>", self.stop_drag)  # 鼠标左键释放

        # 拖动相关的变量
        self.drag_data = {"x": 0, "y": 0, "dragging": False}

        # 创建画布
        self.canvas = tk.Canvas(master, bg='white', highlightthickness=0)
        self.canvas.pack(expand=tk.YES, fill=tk.BOTH)

        # 初始绘制
        self.on_resize()

    def show_context_menu(self, event):
        """显示右键菜单"""
        self.context_menu.post(event.x_root, event.y_root)

    def zoom_in(self):
        """放大窗口, 每次放大10%"""
        current_width = self.master.winfo_width()
        current_height = self.master.winfo_height()
        new_width = int(current_width * 1.1)  # 放大10%
        new_height = int(current_height * 1.1)  # 放大10%
        self.master.geometry(f"{new_width}x{new_height}")  # 设置窗口大小为500x500
        

    def zoom_out(self):
        """缩小窗口, 每次缩小10%"""
        current_width = self.master.winfo_width()
        current_height = self.master.winfo_height()
        new_width = int(current_width * 0.9)  # 缩小10%
        new_height = int(current_height * 0.9)  # 缩小10%
        self.master.geometry(f"{new_width}x{new_height}")  # 设置窗口大小为500x500
        

    def close_window(self):
        """关闭窗口"""
        self.master.destroy()  # 关闭窗口

    def start_drag(self, event):
        """记录鼠标按下时的初始位置"""
        self.drag_data["x"] = event.x
        self.drag_data["y"] = event.y
        self.drag_data["dragging"] = True

    def drag_window(self, event):
        """拖动窗口"""
        if self.drag_data["dragging"]:
            # 计算窗口的新位置
            x = self.master.winfo_x() + (event.x - self.drag_data["x"])
            y = self.master.winfo_y() + (event.y - self.drag_data["y"])
            self.master.geometry(f"+{x}+{y}")  # 设置窗口的新位置

    def stop_drag(self, event):
        """停止拖动"""
        self.drag_data["dragging"] = False

    def on_resize(self, event=None):
        """窗口大小改变时重新绘制时钟"""
        # 获取当前画布尺寸
        self.width = self.canvas.winfo_width()
        self.height = self.canvas.winfo_height()

        # 计算时钟参数
        self.radius = min(self.width, self.height) * 0.48  # 半径为窗口较小尺寸的48%
        self.center_x = self.width // 2
        self.center_y = self.height // 2

        # 清除画布并重新绘制
        self.canvas.delete("all")
        self.draw_clock_face()        
        self.update_time()

    def draw_clock_face(self):
        """绘制钟面"""
        # 设置钟面的边框
        self.canvas.create_oval(
            self.center_x - self.radius,
            self.center_y - self.radius,
            self.center_x + self.radius,
            self.center_y + self.radius,
            fill="#f2f2f2",
            outline="#99ffbb", width=4
        )
        a1 = self.radius-self.radius*0.05
        self.canvas.create_oval(
            self.center_x - a1,
            self.center_y - a1,
            self.center_x + a1,
            self.center_y + a1,
            fill="#99ffbb",
            outline="#99ffbb", width=4
        )
        
        # 绘制刻度线和数字
        for i in range(60):
            angle = i * (2 * pi / 60) - pi / 2  # 将角度转换为弧度,并调整起始位置(从12点开始)
            if i % 5 == 0:  # 每5分钟有一个较长的刻度
                length = self.radius * 0.05  # 刻度长度按比例计算
                # 数字标签的角度应与刻度线角度一致
                hour_num = (i // 5) % 12
                hour_num = 12 if hour_num == 0 else hour_num  # 将0点显示为12
                text_radius = self.radius * 0.85  # 数字离中心距离按比例计算
                x = self.center_x + text_radius * cos(angle)
                y = self.center_y + text_radius * sin(angle)
                font_size = max(10, int(self.radius * 0.15))  # 字体大小按比例计算
                self.canvas.create_text(x, y, text=str(hour_num),font=("Helvetica", font_size, "bold"))
            else:
                length = self.radius * 0.025  # 短刻度长度

            x1 = self.center_x + (self.radius - length) * cos(angle)
            y1 = self.center_y + (self.radius - length) * sin(angle)
            x2 = self.center_x + self.radius * cos(angle)
            y2 = self.center_y + self.radius * sin(angle)

            self.canvas.create_line(x1, y1, x2, y2, fill='#00995c', width=2 if i % 5 == 0 else 1)

        # 中心点装饰
        dot_size = max(3, self.radius * 0.02)  # 中心点大小按比例计算
        self.canvas.create_oval(
            self.center_x - dot_size,
            self.center_y - dot_size,
            self.center_x + dot_size,
            self.center_y + dot_size,
            fill='black'
        )

    def update_time(self):
        """获取当前时间并更新指针位置"""
        now = datetime.now()
        hour = now.hour % 12
        minute = now.minute
        second = now.second

        # 计算每个指针的角度
        hour_angle = (hour + minute / 60) * (pi / 6) - pi / 2
        minute_angle = (minute + second / 60) * (pi / 30) - pi / 2
        second_angle = second * (pi / 30) - pi / 2

        # 删除旧的指针
        self.canvas.delete("hand")
        # 更新日期显示
        self.update_date_display()

        # 绘制新的指针
        self.draw_hand(hour_angle, length=self.radius * 0.5, color='#0033***', width=self.radius * 0.02)
        self.draw_hand(minute_angle, length=self.radius * 0.7, color='#0000***', width=self.radius * 0.015)
        self.draw_hand(second_angle, length=self.radius * 0.8, color='red', width=self.radius * 0.01)

        # 每隔一秒重新绘制一次
        self.master.after(1000, self.update_time)

    def update_date_display(self):
        """更新日期和星期显示"""
        # 格式化日期和星期
        now = datetime.now()
        date_str = now.strftime("%Y年%m月%d日")
        weekday_str = now.strftime("星期%a")

        # 删除旧内容(通过标签精准定位)
        self.canvas.delete("date", "weekday")
        # 星期转换为中文
        weekday_map = {
            "Mon": "一", "Tue": "二", "Wed": "三",
            "Thu": "四", "Fri": "五", "Sat": "六", "Sun": "日"
        }
        for eng, chn in weekday_map.items():
            weekday_str = weekday_str.replace(eng, chn)

        # 计算字体大小
        font_size = max(10, int(self.radius * 0.1))

        # 创建日期和星期标签
        self.canvas.create_text(
            self.center_x, self.center_y - self.radius * 0.2,
            text=date_str,  font=("Helvetica", font_size, "bold"),
            tags="date"
        )
        self.canvas.create_text(
            self.center_x, self.center_y + self.radius * 0.2,
            text=weekday_str, font=("Helvetica", font_size, "bold"),
            tags="weekday"
        )

    def draw_hand(self, angle, length, color, width):
        """根据给定的角度和长度绘制指针"""
        end_x = self.center_x + length * cos(angle)
        end_y = self.center_y + length * sin(angle)
        return self.canvas.create_line(
            self.center_x, self.center_y,
            end_x, end_y,
            fill=color, width=max(1, int(width)),  # 确保最小线宽为1
            tags="hand"
        )


if __name__ == "__main__":
    root = tk.Tk()
    root.title("可缩放模拟时钟")
    root.attributes("-transparentcolor", "white") # 设置透明背景颜色

    screen_width = root.winfo_screenwidth()
    screen_height = root.winfo_screenheight()
    window_width = 400
    window_height = 400

    # 计算窗口位置
    x_position = screen_width - window_width - 100  # 距离右边 100 像素
    y_position = 50 # 距离上边 50 像素

    # 设置窗口初始位置和大小
    root.geometry(f"{window_width}x{window_height}+{x_position}+{y_position}")

    clock = AnalogClock(root)
    root.mainloop()

 

 

转载请说明出处内容投诉
CSS教程网 » 使用python语言的tkinter、math、datetime模块编写的精美夜光模拟时钟,右键可以放大、缩小、关闭

发表评论

欢迎 访客 发表评论

一个令你着迷的主题!

查看演示 官网购买