這是通過python程序制作時鐘的源碼,大家可做參考
- import tkinter as tk
- import math
- import time
- import threading
- import socket
- import datetime
- class AnalogClock:
- def __init__(self, root):
- self.root = root
- self.root.title("Python 模擬鐘表(可縮放)")
- self.root.minsize(200, 200) # 最小窗口尺寸
- self.canvas = tk.Canvas(root, bg='white')
- self.canvas.pack(fill=tk.BOTH, expand=True)
- # 中心點和半徑(將在 draw_face 中計算)
- self.center_x = 200
- self.center_y = 200
- self.radius = 180
- # 時間變量
- self.hour = 0
- self.minute = 0
- self.second = 0
- self.use_system_time = True
- # 綁定窗口大小變化事件
- self.canvas.bind("<Configure>", self.on_resize)
- # 初次繪制表盤和啟動時鐘更新
- self.draw_face()
- self.update_clock()
- # 啟動 TCP 服務器(獨立線程)
- self.server_thread = threading.Thread(target=self.start_tcp_server, daemon=True)
- self.server_thread.start()
- def draw_face(self):
- """根據當前畫布尺寸重繪表盤(刻度、數字),同時更新中心點和半徑"""
- # 刪除舊表盤元素(保留指針,因為指針由 update_clock 管理)
- self.canvas.delete("face")
- # 獲取當前畫布尺寸
- w = self.canvas.winfo_width()
- h = self.canvas.winfo_height()
- if w < 10 or h < 10:
- return # 避免初始尺寸過小
- self.center_x = w // 2
- self.center_y = h // 2
- self.radius = min(w, h) // 2 - 20 # 留出邊距
- # 繪制 12 個刻度及數字
- for i in range(12):
- angle = math.radians(i * 30 - 90) # 12點方向為0度
- # 長刻度線
- x1 = self.center_x + (self.radius - 10) * math.cos(angle)
- y1 = self.center_y + (self.radius - 10) * math.sin(angle)
- x2 = self.center_x + (self.radius - 25) * math.cos(angle)
- y2 = self.center_y + (self.radius - 25) * math.sin(angle)
- self.canvas.create_line(x1, y1, x2, y2, width=3, tags="face")
- # 數字
- num_x = self.center_x + (self.radius - 40) * math.cos(angle)
- num_y = self.center_y + (self.radius - 40) * math.sin(angle)
- self.canvas.create_text(num_x, num_y, text=str(i+1),
- font=('Arial', int(self.radius/10), 'bold'),
- tags="face")
- # 中心圓點(始終在最上層,用單獨的 tag 或不參與刪除)
- self.canvas.create_oval(self.center_x-8, self.center_y-8,
- self.center_x+8, self.center_y+8,
- fill='black', tags="face")
- def on_resize(self, event):
- """窗口尺寸變化時重繪表盤(指針由 update_clock 自動適配)"""
- self.draw_face()
- def update_clock(self):
- """每秒更新指針(使用當前中心點和半徑)"""
- # 獲取系統時間(若處于系統模式)
- if self.use_system_time:
- now = datetime.datetime.now()
- self.hour = now.hour % 12
- self.minute = now.minute
- self.second = now.second
- # 刪除舊指針
- self.canvas.delete("hands")
- # 計算角度(12點方向為0度)
- sec_angle = math.radians(self.second * 6 - 90)
- min_angle = math.radians((self.minute + self.second/60) * 6 - 90)
- hour_angle = math.radians((self.hour + self.minute/60) * 30 - 90)
- # 繪制指針(長度相對半徑)
- self.draw_hand(sec_angle, self.radius * 0.85, width=1, color='red', tag='hands')
- self.draw_hand(min_angle, self.radius * 0.70, width=3, color='blue', tag='hands')
- self.draw_hand(hour_angle, self.radius * 0.50, width=5, color='black', tag='hands')
- # 繼續下一幀
- self.root.after(1000, self.update_clock)
- def draw_hand(self, angle, length, width=2, color='black', tag=''):
- x = self.center_x + length * math.cos(angle)
- y = self.center_y + length * math.sin(angle)
- self.canvas.create_line(self.center_x, self.center_y, x, y,
- width=width, fill=color, tags=tag)
- # ---------- TCP 服務器(保持不變) ----------
- def start_tcp_server(self):
- host = '127.0.0.1'
- port = 8888
- with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as s:
- s.bind((host, port))
- s.listen(1)
- print(f"TCP 服務器已啟動,監聽 {host}:{port}")
- while True:
- conn, addr = s.accept()
- with conn:
- print(f"連接來自 {addr}")
- while True:
- data = conn.recv(1024).decode().strip()
- if not data:
- break
- response = self.process_command(data)
- conn.sendall(response.encode())
- if data.lower() == 'exit':
- return
- def process_command(self, cmd):
- cmd = cmd.strip().lower()
- if cmd == 'get_time':
- return f"{self.hour:02d}:{self.minute:02d}:{self.second:02d}"
- elif cmd.startswith('set_time'):
- try:
- parts = cmd.split()
- if len(parts) == 2:
- t = parts[1]
- h, m, s = map(int, t.split(':'))
- if 0 <= h < 24 and 0 <= m < 60 and 0 <= s < 60:
- self.hour = h % 12
- self.minute = m
- self.second = s
- self.use_system_time = False
- return "OK: Time set"
- else:
- return "ERROR: Invalid time"
- except:
- return "ERROR: Format must be 'set_time HH:MM:SS'"
- elif cmd == 'reset_system_time':
- self.use_system_time = True
- return "OK: Switched to system time"
- elif cmd == 'exit':
- return "Goodbye"
- else:
- return f"Unknown command: {cmd}"
- if __name__ == "__main__":
- root = tk.Tk()
- clock = AnalogClock(root)
- root.mainloop()
復制代碼
|