基于Python寫一個番茄鐘小工具
一、功能簡述
番茄鐘即番茄工作法,番茄工作法是簡單易行的時間管理工具,使用番茄工作法即一個番茄時間共30分鐘,25分鐘工作,5分鐘休息;
特點一:番茄時長有三檔
因為這個工具本人也是考慮到每個人情況不一樣,不一定25分鐘就適合自己,所以將番茄鐘時長設(shè)為30min/45min/60min三檔,自由選擇
特點二:番茄統(tǒng)計功能
特點三:休息期間會自動播放放松音樂,當(dāng)然不喜歡也支持禁止播放放松音樂,休息時間結(jié)束后,音樂也會自動停止(意味著又要開始“搬磚”了)
特點四:番茄鐘結(jié)束后,會有蜂鳴音提示,并且跳出彈框
二、使用到的主要模塊
tkinter:用于界面設(shè)計
winsound:用于調(diào)用蜂鳴器提示音
pygame:用于音樂播放
time:時間相關(guān)的格式轉(zhuǎn)換
三、核心模塊代碼分析
代碼的主要思路是主函數(shù)中,利用tkinter模塊布局界面、按鈕、標(biāo)簽等組件,然后將番茄鐘、休息兩大核心功能封裝到函數(shù)中,一旦點擊對應(yīng)的按鈕,即開啟一個新線程用于執(zhí)行對應(yīng)的功能,同時通過全局變量thread_flag來保持永遠(yuǎn)只有主線程和功能線程2個線程,避免多次點擊,產(chǎn)生多個線程同時運行,造成番茄鐘混亂;
1、番茄鐘模塊
## 創(chuàng)建番茄計時函數(shù) def tomato_clock(remain_time): # 如果在休息時間未結(jié)束就開啟番茄鐘,則停止音樂 pygame.mixer.music.pause() # 用來提醒用戶選擇番茄鐘時長,為選擇的話,就跳出函數(shù),結(jié)束線程 if remain_time == 0: lb3.configure(text='請先選擇番茄鐘時長') return print(remain_time) # gmtime這里是將時間轉(zhuǎn)化為計算機可處理的時間格式即time_t到tm類型的轉(zhuǎn)換;不是重點,知道是格式轉(zhuǎn)化即可 # strptime()函數(shù)將字符串轉(zhuǎn)換為datetime begin_time = time.strftime('%M:%S', time.gmtime(remain_time)) # 將時間內(nèi)容打印到界面上 lb2.configure(text=begin_time) lb3.configure(text='總時間/剩余時間') # 用于保證番茄鐘線程或者休息線程只有一個能存在,這個也是本人覺得比較巧的一個點 global thread_flag if thread_flag: thread_flag = False else: thread_flag = True tmp_thread_flag = thread_flag # 時間變化部分 for i in range(remain_time): # 如果收到休息線程導(dǎo)致的thread_flag標(biāo)志位的變化,則退出線程 if tmp_thread_flag != thread_flag: return remain_time -= 1 remain_time_str = time.strftime('/ %M:%S', time.gmtime(remain_time)) # 將時鐘實時更新到界面上 lb1.configure(text=remain_time_str) root.update() time.sleep(1) #時間到了,開啟蜂鳴提醒與提示框提醒 if remain_time == 0: Beep(500, 800) tomato_count() mymsg() lb1.configure(text=begin_time) #使用者確認(rèn)后,自動進(jìn)入休息模式 relax()
2、音樂控制函數(shù)
# 音樂控制函數(shù),用來控制是否允許休息時播放音樂,其實本質(zhì)只是靜音而已,狗頭.jpg # 在定義時,music_flag已經(jīng)初始化True,代表運行休息時播放音樂 def music_allow(): global music_flag #聲明全局變量 # 如果已經(jīng)是True(即不禁止音樂時),勾選了按鈕,則music_flag 變?yōu)?False,禁止音樂 if music_flag: music_flag = False pygame.mixer.music.set_volume(0.0) else: # 代表取消勾選,不禁止音樂 music_flag = True pygame.mixer.music.set_volume(0.5)
3、main中的按鈕部分
# 每當(dāng)按鈕點擊后,就會產(chǎn)生一個線程,執(zhí)行對應(yīng)的功能,和主線程并行 # 以防止單線程的話,進(jìn)入番茄鐘或者休息時,界面中的其他功能按鈕失效 # 開啟番茄鐘按鈕,使用lambda構(gòu)造匿名函數(shù)是因為command后接的函數(shù)如果有參數(shù)會失效,這點本人也不清楚,沒去深究,直接匿名函數(shù)走去 # 同時daemon=True,即將線程設(shè)為守護(hù)線程,解決主線程退出時,其他線程不正常退出的問題 Button1 = tk.Button(root, text='開啟一個番茄', bg='orange', fg='black', font='Verdana 13 bold',width=15, height=1, command=lambda: threading.Thread(target=tomato_clock, daemon=True,args=(var.get(),)).start()) Button1.place(x=70, y=150) # 休息一下按鈕 Button2 = tk.Button(root, text='休息一下', bg='cornflowerblue', fg='black', font='Verdana 13 bold', width=15,height=1,command=lambda:threading.Thread(target=relax,daemon=True).start()) Button2.place(x=70, y=200)
四、整體代碼
# -*- coding:utf-8 -*- import tkinter as tk import tkinter.messagebox from winsound import Beep import threading import sys import pygame import time # 用于統(tǒng)計完成的番茄鐘個數(shù) count = 0 # 線程切換標(biāo)志 thread_flag = True # 音樂開關(guān)標(biāo)志 music_flag = True # 調(diào)用Tk()創(chuàng)建主窗口 root = tk.Tk() # 給主窗口起一個名字,也就是窗口的名字 root.title('Rio的番茄鐘') # 設(shè)置窗口大小:寬x高,注,此處不能為 "*",必須使用 "x" root.geometry('460x300') root.configure(bg='Tomato') # 創(chuàng)建完成計時后的彈窗 def mymsg(): try: tk.messagebox.showinfo("提示", "恭喜完成一個番茄鐘?。∮浀眯菹⒁幌?) except Exception as e: print(type(e), e) sys.exit() # 休息結(jié)束彈窗 def mymsg2(): tk.messagebox.showinfo("提示", "休息完畢!") # 創(chuàng)建番茄計時函數(shù) # strptime()函數(shù)將字符串轉(zhuǎn)換為datetime def tomato_clock(remain_time): # 如果在休息時間未結(jié)束就開啟番茄鐘,則停止音樂 pygame.mixer.music.pause() # 避免未進(jìn)行番茄鐘時長選擇 if remain_time == 0: lb3.configure(text='請先選擇番茄鐘時長') return print(remain_time) begin_time = time.strftime('%M:%S', time.gmtime(remain_time)) lb2.configure(text=begin_time) lb3.configure(text='總時間/剩余時間') global thread_flag if thread_flag: thread_flag = False else: thread_flag = True tmp_thread_flag = thread_flag for i in range(remain_time): if tmp_thread_flag != thread_flag: return remain_time -= 1 remain_time_str = time.strftime('/ %M:%S', time.gmtime(remain_time)) lb1.configure(text=remain_time_str) root.update() time.sleep(1) if remain_time == 0: Beep(500, 800) tomato_count() mymsg() lb1.configure(text=begin_time) relax() # 創(chuàng)建番茄計數(shù)的函數(shù) def tomato_count(): global count count += 1 lb4.configure(text=count) # 創(chuàng)建休息時間函數(shù) def relax(): remain_time = 480 # 休息8分鐘 begin_time = time.strftime('%M:%S', time.gmtime(remain_time)) lb2.configure(text=begin_time) lb3.configure(text='總時間/剩余時間') # 線程標(biāo)志,用于結(jié)束舊線程 global thread_flag if thread_flag: thread_flag = False else: thread_flag = True tmp_thread_flag = thread_flag pygame.mixer.music.play(-1) for i in range(remain_time): if tmp_thread_flag != thread_flag: return remain_time -= 1 remain_time_str = time.strftime('/ %M:%S', time.gmtime(remain_time)) lb1.configure(text=remain_time_str) root.update() time.sleep(1) if remain_time == 0: pygame.mixer.music.pause() mymsg2() lb1.configure(text=begin_time) # 音樂控制函數(shù) def music_allow(): global music_flag # 如果已經(jīng)是True(即不禁止音樂時),勾選了按鈕,則music_flag 變?yōu)?False,禁止音樂 if music_flag: music_flag = False pygame.mixer.music.set_volume(0.0) else: music_flag = True pygame.mixer.music.set_volume(0.5) if __name__ == "__main__": #音樂初始化 pygame.mixer.init() # 異常拋出,防止沒有放音樂文件 try: pygame.mixer.music.load('music.mp3') except Exception as e: print(type(e), e) tk.messagebox.showinfo("提示", "無文件music.mp3或改文件路徑不對") sys.exit() pygame.mixer.music.set_volume(0.5) # 創(chuàng)建變量 var = tk.IntVar() # 給變量賦初值為30 var.set(30) # 番茄動態(tài)計時 lb1 = tk.Label(root, text='0', bg='Tomato', fg='white', font='Verdana 16 bold', width=7, height=1) lb1.place(x=130, y=100) # 番茄固定時間 lb2 = tk.Label(root, text='0', bg='Tomato', fg='white', font='Verdana 16 bold', width=5, height=1) lb2.place(x=60, y=100) # 剩余時間/總時間 lb3 = tk.Label(root, text=' ', bg='Tomato', fg='white', font='Verdana 16 bold', width=14, height=2) lb3.place(x=50, y=44) # 番茄個數(shù)顯示 lb4 = tk.Label(root, text='0', bg='Tomato', fg='white', font='Verdana 16 bold', width=7, height=1) lb4.place(x=90, y=20) # 左上角的 番茄: lb5 = tk.Label(root, text='已積累番茄:', bg='Tomato', fg='white', font='Verdana 16 bold', width=8, height=1) lb5.place(x=5, y=20) # 按鈕 ##創(chuàng)造一個frame來收納按鈕 fr1 = tk.LabelFrame(root,bg='LightGreen',text='選擇番茄鐘時長', relief='groove', bd=1,) fr1.pack(side='right') r1 = tk.Radiobutton(fr1, text='30min', variable=var, bg='LightGreen', value=1800) r1.pack() r2 = tk.Radiobutton(fr1, text='45min', variable=var, bg='LightGreen', value=2700) r2.pack() r3 = tk.Radiobutton(fr1, text='60min', variable=var, bg='LightGreen', value=3599) r3.pack() Checkbutton = tk.Checkbutton(fr1, text="是否禁止音樂", fg='black', bg='LightGreen', command=music_allow) Checkbutton.pack() # 開啟一個番茄 #利用多線程,避免進(jìn)入番茄鐘后,退出按鈕失效 Button1 = tk.Button(root, text='開啟一個番茄', bg='orange', fg='black', font='Verdana 13 bold',width=15, height=1, command=lambda: threading.Thread(target=tomato_clock, daemon=True,args=(var.get(),)).start()) Button1.place(x=70, y=150) # 休息一下 Button2 = tk.Button(root, text='休息一下', bg='cornflowerblue', fg='black', font='Verdana 13 bold', width=15, height=1, command=lambda: threading.Thread(target=relax, daemon=True).start()) Button2.place(x=70, y=200) # 添加按鈕,以及按鈕的文本,并通過command 參數(shù)設(shè)置關(guān)閉窗口的功能 button = tk.Button(root, text="退出", fg='black', bg='YellowGreen', width=15, command=root.quit) # 將按鈕放置在主窗口內(nèi) button.place(x=105, y=250) #開啟主循環(huán),讓窗口處于顯示狀態(tài) root.mainloop()
到此這篇關(guān)于基于Python寫一個番茄鐘小工具的文章就介紹到這了,更多相關(guān)Python番茄鐘內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
python將紅底證件照轉(zhuǎn)成藍(lán)底的實現(xiàn)方法
這篇文章主要介紹了python將紅底證件照轉(zhuǎn)成藍(lán)底,本文給大家分享四種方法通過示例代碼給大家介紹的非常詳細(xì),對大家的學(xué)習(xí)或工作具有一定的參考借鑒價值,需要的朋友可以參考下2022-08-08在pycharm中執(zhí)行 os.makedirs 提示用戶名或密碼不正確的問題及解決方法
這篇文章主要介紹了在pycharm中執(zhí)行 os.makedirs 提示用戶名或密碼不正確的問題及解決方法,本文給大家介紹的非常詳細(xì),對大家的學(xué)習(xí)或工作具有一定的參考借鑒價值,需要的朋友參考下吧2024-01-01Python函數(shù)式編程之返回函數(shù)實例詳解
函數(shù)式編程的一個特點就是,允許把函數(shù)本身作為參數(shù)傳入另一個函數(shù),還允許返回一個函數(shù),下面這篇文章主要給大家介紹了關(guān)于Python函數(shù)式編程之返回函數(shù)的相關(guān)資料,需要的朋友可以參考下2022-09-09