使用Python代碼實(shí)現(xiàn)番茄鐘功能
一、項(xiàng)目簡介
本代碼是一款基于 Python Tkinter 開發(fā)的極簡懸浮番茄鐘,僅 91 行核心代碼實(shí)現(xiàn)番茄工作法核心功能:自定義計(jì)時(shí)時(shí)長、懸浮置頂顯示、倒計(jì)時(shí)結(jié)束提醒、倒計(jì)時(shí)最后 1 秒背景閃爍提醒,兼顧實(shí)用性與視覺體驗(yàn),適配 Windows 系統(tǒng),代碼精簡且功能完整。
二、核心功能亮點(diǎn)
- 懸浮置頂設(shè)計(jì):窗口置頂且透明背景,不遮擋其他操作,辦公學(xué)習(xí)時(shí)隨時(shí)可見;
- 自定義時(shí)長:支持 1-60 分鐘自定義計(jì)時(shí)(輸入異常自動(dòng)重置為 25 分鐘);
- 視覺 + 聽覺雙重提醒:倒計(jì)時(shí)最后 1 秒背景高頻閃爍,計(jì)時(shí)結(jié)束觸發(fā)雙頻蜂鳴音;
- 極簡交互:僅輸入框 + 開始按鈕,操作無學(xué)習(xí)成本,符合番茄鐘 “專注” 核心訴求。
三、代碼核心邏輯拆解
| 代碼段 | 功能說明 |
|---|---|
| 1-18 行 | 初始化窗口:設(shè)置懸浮、置頂、透明背景、位置(屏幕右上角),定義核心變量(計(jì)時(shí)狀態(tài)、剩余時(shí)間等) |
| 19-29 行 | UI 搭建:極簡布局(計(jì)時(shí)顯示標(biāo)簽 + 時(shí)長輸入框 + 開始按鈕),配色選用護(hù)眼淺綠 + 透明底色 |
| 30-33 行 | 時(shí)間格式化顯示:將秒數(shù)轉(zhuǎn)換為 “分:秒” 格式,實(shí)時(shí)更新標(biāo)簽 |
| 34-45 行 | 倒計(jì)時(shí)核心:每秒遞減時(shí)間,最后 1 秒觸發(fā)背景閃爍,計(jì)時(shí)結(jié)束調(diào)用提醒邏輯 |
| 46-52 行 | 背景閃爍:最后 1 秒高頻切換背景色,強(qiáng)化視覺提醒 |
| 53-58 行 | 聽覺提醒:雙頻蜂鳴音(800Hz+1000Hz),兼容系統(tǒng)發(fā)聲異常場景 |
| 59-75 行 | 開始 / 重置邏輯:清空舊計(jì)時(shí)任務(wù)、校驗(yàn)輸入時(shí)長、重置狀態(tài)變量、啟動(dòng)新倒計(jì)時(shí) |
| 76-80 行 | 程序入口:創(chuàng)建主窗口、實(shí)例化番茄鐘、啟動(dòng)主循環(huán) |
四、創(chuàng)意設(shè)計(jì)思路
極簡主義:拒絕冗余 UI,僅保留核心交互元素,符合番茄鐘 “專注” 的使用場景;
沉浸式提醒:最后 1 秒背景閃爍 + 結(jié)束蜂鳴,避免錯(cuò)過計(jì)時(shí)節(jié)點(diǎn),比單一聲音提醒更有效;
容錯(cuò)設(shè)計(jì):輸入非數(shù)字 / 超出范圍自動(dòng)重置為 25 分鐘,降低用戶操作失誤成本;
懸浮體驗(yàn):窗口固定在屏幕右上角,透明背景不干擾其他工作,兼顧 “可見” 與 “不打擾”。
五、使用說明
運(yùn)行代碼后,番茄鐘窗口自動(dòng)懸浮在屏幕右上角;
在輸入框中輸入 1-60 的數(shù)字(代表分鐘),點(diǎn)擊 “開始” 即可啟動(dòng)倒計(jì)時(shí);
倒計(jì)時(shí)最后 1 秒,窗口背景會(huì)高頻閃爍;
計(jì)時(shí)結(jié)束后,系統(tǒng)會(huì)發(fā)出雙頻蜂鳴音提醒,同時(shí)自動(dòng)重置為設(shè)定時(shí)長。
六、代碼創(chuàng)新點(diǎn)
僅 91 行代碼實(shí)現(xiàn)完整番茄鐘功能,無冗余邏輯,變量命名簡潔易懂;
結(jié)合視覺(背景閃爍)+ 聽覺(蜂鳴)雙重提醒,比傳統(tǒng)番茄鐘更人性化;
透明懸浮窗口設(shè)計(jì),適配多場景使用(辦公、學(xué)習(xí)、刷題等);
輸入容錯(cuò)機(jī)制,避免用戶誤操作導(dǎo)致程序異常。
七、項(xiàng)目代碼
安裝Python環(huán)境后,新建.py文件,復(fù)制保存,雙擊運(yùn)行即可
import tkinter as tk
from tkinter import ttk
import time
import winsound
class TomatoClock:
def __init__(self, root):
self.root = root
self.root.title("番茄鐘")
self.root.geometry("320x200")
self.root.overrideredirect(True)
self.root.wm_attributes("-topmost", 1)
self.root.update_idletasks()
sw = self.root.winfo_screenwidth()
self.root.geometry(f"320x200+{sw-330}+10")
self.tc = "#000001"
self.root.wm_attributes("-transparentcolor", self.tc)
self.root.wm_attributes("-alpha", 0.95)
self.lg = "#90EE90"
self.is_running = False
self.work_time = 25 * 60
self.remaining = self.work_time
self.timer_id = None
self.flash_count = 0
self.is_flashing = False
self.setup_ui()
self.update_display()
def setup_ui(self):
self.mf = tk.Frame(self.root, bg=self.tc, highlightthickness=0)
self.mf.place(relwidth=1, relheight=1)
self.tl = tk.Label(self.mf, text="25:00", font=("微軟雅黑", 42, "bold"), bg=self.tc, fg=self.lg)
self.tl.pack(pady=5)
self.bf = tk.Frame(self.mf, bg=self.tc)
self.bf.pack(pady=15)
self.te = ttk.Entry(self.bf, width=8)
self.te.insert(0, "25")
self.te.grid(row=0, column=0, padx=5)
self.sb = ttk.Button(self.bf, text="開始", command=self.start_timer, width=8)
self.sb.grid(row=0, column=1, padx=5)
def update_display(self):
m = self.remaining // 60
s = self.remaining % 60
self.tl.config(text=f"{m:02d}:{s:02d}")
def countdown(self):
if self.is_running and self.remaining > 0:
if self.remaining == 1 and not self.is_flashing:
self.is_flashing = True
self.flash_background()
self.remaining -= 1
self.update_display()
self.timer_id = self.root.after(1000, self.countdown)
elif self.remaining == 0:
self.is_running = False
self.is_flashing = False
self.alarm()
self.flash_count = 0
self.mf.config(bg=self.tc)
self.tl.config(bg=self.tc)
self.remaining = self.work_time
self.update_display()
def flash_background(self):
if self.is_flashing and self.flash_count < 20:
cb = self.mf.cget("bg")
nb = self.lg if cb == self.tc else self.tc
self.mf.config(bg=nb)
self.tl.config(bg=nb)
self.flash_count += 1
self.root.after(50, self.flash_background)
def alarm(self):
try:
winsound.Beep(800, 500)
winsound.Beep(1000, 500)
except:
pass
def start_timer(self):
if self.timer_id:
self.root.after_cancel(self.timer_id)
self.is_flashing = False
self.flash_count = 0
self.mf.config(bg=self.tc)
self.tl.config(bg=self.tc)
try:
cm = int(self.te.get())
if cm <= 0 or cm > 60:
cm = 25
self.te.delete(0, tk.END)
self.te.insert(0, "25")
except ValueError:
cm = 25
self.te.delete(0, tk.END)
self.te.insert(0, "25")
self.work_time = cm * 60
self.remaining = self.work_time
self.is_running = True
self.update_display()
self.countdown()
if __name__ == "__main__":
r = tk.Tk()
app = TomatoClock(r)
r.mainloop()到此這篇關(guān)于使用Python代碼實(shí)現(xiàn)番茄鐘功能的文章就介紹到這了,更多相關(guān)Python番茄鐘功能內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
Pytorch保存模型用于測(cè)試和用于繼續(xù)訓(xùn)練的區(qū)別詳解
今天小編就為大家分享一篇Pytorch保存模型用于測(cè)試和用于繼續(xù)訓(xùn)練的區(qū)別詳解,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過來看看吧2020-01-01
PyQt通過動(dòng)畫實(shí)現(xiàn)平滑滾動(dòng)的QScrollArea
這篇文章主要為大家詳細(xì)介紹了PyQt如何使用Qt的動(dòng)畫框架 QPropertyAnimation來實(shí)現(xiàn)平滑滾動(dòng)的QScrollArea,文中的示例代碼講解詳細(xì),具有一定的借鑒價(jià)值,感興趣的可以學(xué)習(xí)一下2023-01-01
利用Python進(jìn)行數(shù)據(jù)可視化的實(shí)例代碼
數(shù)據(jù)可視化和數(shù)據(jù)挖掘都是探索數(shù)據(jù)和分析數(shù)據(jù)的一種手段,下面這篇文章主要給大家介紹了關(guān)于如何利用Python進(jìn)行數(shù)據(jù)可視化的相關(guān)資料,文中通過示例代碼介紹的非常詳細(xì),需要的朋友可以參考下2021-09-09
python實(shí)現(xiàn)tail實(shí)時(shí)查看服務(wù)器日志示例
今天小編就為大家分享一篇python實(shí)現(xiàn)tail實(shí)時(shí)查看服務(wù)器日志示例,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過來看看吧2019-12-12
pycharm的console輸入實(shí)現(xiàn)換行的方法
今天小編就為大家分享一篇pycharm的console輸入實(shí)現(xiàn)換行的方法,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過來看看吧2019-01-01
Django Haystack 全文檢索與關(guān)鍵詞高亮的實(shí)現(xiàn)
這篇文章主要介紹了Django Haystack 全文檢索與關(guān)鍵詞高亮的實(shí)現(xiàn),文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2020-02-02
python數(shù)據(jù)庫操作常用功能使用詳解(創(chuàng)建表/插入數(shù)據(jù)/獲取數(shù)據(jù))
這篇文章主要介紹了python數(shù)據(jù)庫操作常用功能使用方法:獲取mysql版本、創(chuàng)建表、插入數(shù)據(jù)、slect獲取數(shù)據(jù)等,下面看示例吧2013-12-12
Pycharm連接gitlab實(shí)現(xiàn)過程圖解
這篇文章主要介紹了Pycharm連接gitlab實(shí)現(xiàn)過程圖解,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下2020-09-09

