這個 Python 程式是一個簡單的番茄鐘(Pomodoro timer)應用程序,它使用 tkinter 來創建一個 GUI,並使用 threading 來處理時間。番茄鐘是一種時間管理方法,通常將工作時間和休息時間分別設定為 25 分鐘和 5 分鐘。

程式碼解釋

導入模塊

1
2
import tkinter as tk
import winsound

在這裡,我們導入了兩個模塊:tkinterwinsoundtkinter 是 Python 的標準 GUI 庫,winsound 是 Windows 平台專用的聲音播放模塊。

TomatoClock 類

1
2
3
4
5
6
7
8
9
class TomatoClock:
def __init__(self, work_time=25, rest_time=5):
self.work_time = work_time * 60
self.rest_time = rest_time * 60
self.remaining = self.work_time
self.status = "Work"
self.timer_running = False

self.root = tk.Tk()

TomatoClock 類是我們番茄鐘程序的主體。在 __init__ 方法中,我們設定了工作時間和休息時間(以秒為單位),並初始化了一些用於控制番茄鐘狀態的變量。我們也創建了一個 tkinter 的窗口並將其保存在 self.root 中。

GUI 界面

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
self.label = tk.Label(self.root, text="", font=("Helvetica", 48))
self.label.grid(row=0, column=0, columnspan=3, sticky="nsew")

self.start_button = tk.Button(self.root, text="Start", command=self.start_timer, font=("Helvetica", 20))
self.start_button.grid(row=1, column=0, sticky="nsew")

self.pause_button = tk.Button(self.root, text="Pause", command=self.pause_timer, font=("Helvetica", 20))
self.pause_button.grid(row=1, column=1, sticky="nsew")

self.reset_button = tk.Button(self.root, text="Reset", command=self.reset_timer, font=("Helvetica", 20))
self.reset_button.grid(row=1, column=2, sticky="nsew")

self.always_on_top_var = tk.IntVar()
self.always_on_top_checkbutton = tk.Checkbutton(self.root, text="Always on top", variable=self.always_on_top_var, command=self.set_always_on_top)
self.always_on_top_checkbutton.grid(row=2, column=0, columnspan=3, sticky="nsew")

self.root.grid_rowconfigure(0, weight=1)
self.root.grid_rowconfigure(1, weight=1)
self.root.grid_rowconfigure(2, weight=1)
self.root.grid_columnconfigure(0, weight=1)
self.root.grid_columnconfigure(1, weight=1)
self.root.grid_columnconfigure(2, weight=1)

self.update_label()

在這部分,我們創建了 GUI 界面的元件,包括一個顯示時間的標籤,三個控制番茄鐘的按鈕,以及一個控制窗口是否始終保持在最前面的復選框。我們使用 grid 來管理這些元件的位置。

時間更新

1
2
3
4
5
6
7
8
9
10
11
12
13
14
def update(self):
if not self.timer_running:
return
self.remaining -= 1
if self.remaining <= 0:
winsound.Beep(2000, 800) # Play a beep sound
if self.status == "Work":
self.status = "Rest"
self.remaining = self.rest_time
else:
self.status = "Work"
self.remaining = self.work_time
self.update_label()
self.root.after(1000, self.update)

update 方法用於更新時間。如果番茄鐘正在運行,則減少剩餘時間。如果剩餘時間已經為零,則播放一聲提示音,並切換工作狀態和休息狀態。

其他方法

這個類還有其他一些方法,如 start_timerpause_timerreset_timerset_always_on_top,它們分別用於控制番茄鐘的運行、暫停、重置,以及設定窗口是否始終保持在最前面。

Source code

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
import tkinter as tk
import winsound

class TomatoClock:
def __init__(self, work_time=25, rest_time=5):
self.work_time = work_time * 60
self.rest_time = rest_time * 60
self.remaining = self.work_time
self.status = "Work"
self.timer_running = False

self.root = tk.Tk()

self.label = tk.Label(self.root, text="", font=("Helvetica", 48))
self.label.grid(row=0, column=0, columnspan=3, sticky="nsew")

self.start_button = tk.Button(self.root, text="Start", command=self.start_timer, font=("Helvetica", 20))
self.start_button.grid(row=1, column=0, sticky="nsew")

self.pause_button = tk.Button(self.root, text="Pause", command=self.pause_timer, font=("Helvetica", 20))
self.pause_button.grid(row=1, column=1, sticky="nsew")

self.reset_button = tk.Button(self.root, text="Reset", command=self.reset_timer, font=("Helvetica", 20))
self.reset_button.grid(row=1, column=2, sticky="nsew")

self.always_on_top_var = tk.IntVar()
self.always_on_top_checkbutton = tk.Checkbutton(self.root, text="Always on top", variable=self.always_on_top_var, command=self.set_always_on_top)
self.always_on_top_checkbutton.grid(row=2, column=0, columnspan=3, sticky="nsew")

self.root.grid_rowconfigure(0, weight=1)
self.root.grid_rowconfigure(1, weight=1)
self.root.grid_rowconfigure(2, weight=1)
self.root.grid_columnconfigure(0, weight=1)
self.root.grid_columnconfigure(1, weight=1)
self.root.grid_columnconfigure(2, weight=1)

self.update_label()

def set_always_on_top(self):
if self.always_on_top_var.get() == 1:
self.root.attributes("-topmost", True)
else:
self.root.attributes("-topmost", False)

def start_timer(self):
self.timer_running = True
self.update()

def pause_timer(self):
self.timer_running = False

def reset_timer(self):
self.timer_running = False
self.remaining = self.work_time
self.status = "Work"
self.update_label()

def update(self):
if not self.timer_running:
return
self.remaining -= 1
if self.remaining <= 0:
winsound.Beep(2000, 800) # Play a beep sound
if self.status == "Work":
self.status = "Rest"
self.remaining = self.rest_time
else:
self.status = "Work"
self.remaining = self.work_time
self.update_label()
self.root.after(1000, self.update)

def update_label(self):
minutes, seconds = divmod(self.remaining, 60)
self.label.config(text=f"{self.status}: {minutes}:{seconds:02}")

def run(self):
self.root.mainloop()

if __name__ == "__main__":
clock = TomatoClock()
clock.run()

.py 文件轉換.exe

python_exePackage


作者: 微風