今回の講義はポモドーロ・テクニックという時間管理術を使った
タイマーツールを作成します。
Udemyの講座では背景は変わらずに文字だけかわる仕様でしたが
こんな感じ
自分のツールでは働く時と休憩の時には背景の絵を変えるようにします。
あとはなぜかstartとresetの背景がUdemyの通りにならずグレイになっているので
そこも直しました。
こんな感じ
流れとしては
- tkinterをインポートする
- タイトル・画像・テキスト部分・ボタンを配置する
- スタートボタンを押すとタイマーがはじまる
- ストップボタンを押すとタイマー・文字・画像が最初に戻る
こんな感じですかね。
初めて行きます
tkinter をインポートする
from tkinter import *
YELLOW = "#f6f3e7"
window = Tk()
window.title("Pomodoro")
window.config(bg=YELLOW,padx=30, pady=20)
canvas = Canvas(width=500, height=500)
pc_img = PhotoImage(file="pomodoro1.png")
coffee_img = PhotoImage(file="pomodoro2.png")
bg_image = canvas.create_image(250, 200, image=pc_img)
canvas.config(bg=YELLOW, highlightthickness=0)
timer_text = canvas.create_text(250,360, text="00:00",fill="#333", font=("Futura", 40, "italic"))
canvas.grid(row=1, column=0, rowspan=3, columnspan=3)
YELLOWは背景の色を全て合わせたいので最初に定義しています。
仕事バージョンと休憩バージョンとしてpc_imgとcoffee_imgも最初に定義しています。
タイトル・画像・テキスト部分・ボタンを配置する
title = Label(text="Timer", font=("Futura", 40, "italic"))
title.config(bg=YELLOW)
title.grid(row=0, column=1)
check_mark = Label(text="", font=("Futura", 20, "italic"))
check_mark.config(bg=YELLOW)
check_mark.grid(row=3, column=1)
start_btn = Button(text="start", width=10, highlightbackground=YELLOW, command=start_timer)
start_btn.grid(row=3, column=0,padx=10)
stop_btn = Button(text="stop", width=10, highlightbackground=YELLOW, command=stop_timer)
stop_btn.grid(row=3, column=2)
window.mainloop()
canvasで00:00の表示と背景まですませているので(別々でlabelにしてもいい)
あとはタイトル・スタートボタン・ストップボタンを配置。
ボタンの間に、ポモドーロタイマーのどこまでいってるかを確認するチェックマークも配置します。
休憩を挟むごとにチェックマークがでてきます。
Udemyでは出てこなかったのに、自分のmacではボタン周りの背景がグレーでbg=YELLOWにしても変わらなかったのだけれども、
highlightbackground=YELLOWにすることで解決。
Pycharmでの補助機能で偶然発見できた。
ここまでは基礎的なtkinterのレイアウト方法なので一回勉強したら難しくないはず。
スタートボタンを押すとタイマーがはじまる動作を作る
start_btnのcommand start_timerのファンクションを定義する。
タイマーをスタートする機能と、カウントダウンを始める機能は別個で作成する。
先に秒をカウントする機能。
def count_down(count):
minutes = math.floor(count / 60)
second = count % 60
if second < 10:
second = f"0{second}"
canvas.itemconfig(timer_text, text=f"{minutes}:{second}")
if count > 0:
global timer
timer = window.after(1000, count_down, count - 1)
else:
start_timer()
mark =""
work_sessions = math.floor(repeat/2)
for _ in range(work_sessions):
mark +="✔"
check_mark.config(text=mark)
tkinterではtime をインポートしてsleepみたいな機能はwindow.after()でできる。
1000で1秒を表して、1秒ごとにcount - 1 を繰り返す。0になったら
start_timer()をやり直す。
秒数の表示はcountに入れた秒から60で割り切れない数字を表示する。
minutesでcountに入れた秒数から60を割ることで分を表わす。
なので2分の場合は120秒なので、
minutes = 120 / 60 => 2
second = 120 % 60 => 割り切れるので0
となる。
10以下の場合だと表示が9,8,7と09,08,07表示にならないため、
if second < 10 以下のコーディングで1桁の場合はストリングにして表示するようにしています。
start_timer()
repeat = 0
def start_timer():
global repeat
repeat += 1
work_sec = 25 * 60
break_sec = 5 * 60
break_long_sec = 15 * 60
if start_btn["state"]:
start_btn.config(state=DISABLED)
if repeat % 8 == 0:
count_down(break_long_sec)
title.config(text="Long Break!")
canvas.itemconfig(bg_image, image=coffee_img)
elif repeat % 2 == 0:
count_down(break_sec)
title.config(text="Break...")
canvas.itemconfig(bg_image, image=coffee_img)
else:
count_down(work_sec)
title.config(text="WORK!")
canvas.itemconfig(bg_image, image=pc_img)
repeatでは1回count_downが終わるごとに1を追加して、今どこのタイマーなのかを記録しています。
またここでわかりやすく作業の時間、休憩時間、長休憩時間を定義しています。
秒数で表すので25分なら 25 * 60というような感じで。
if start_btn["state"]:
というのはスタートボタンの状態を表しています。
この書き方だとbooleanなのでTrueの状態であれば動作するようにしています。
スタートボタンを2回以上連打されないようにするために最初にstateをDISABLEDにしています。
Udemyの講座にはない追加機能です。
ポモドーロでは仕事と小休憩を3回はさんで4回目は長休憩をするメソッドなので
入れ子になっているif文のところでは、
repeatが偶数で小休憩を挟むけど 8回目では長休憩をできるよう % を使うことで
動作を分けています。
ここでタイトル部分と背景もチェンジするようにしています。
count_downではカウントが終わったらstart_timerを起動させ、
start_timerではrepeatの回数を見たらすぐにcount_downを起動させるので
ずっと続けるなら無限にループされます。
8回1セットの想定なのですが何セットもされるとチェックマークがどんどん増えて
表示は横長になっていきます。
ストップボタンでタイマーを止める
def stop_timer():
window.after_cancel(timer)
title.config(text="Timer")
canvas.itemconfig(timer_text, text="00:00")
canvas.itemconfig(bg_image, image=pc_img)
check_mark.config(text="")
start_btn.config(state=NORMAL)
global repeat
repeat = 0
タイマーを止めるには、defのidではなく、window.afterをとめる必要があります。
window.after_cancel(window.afterを定義している変数)で止められます。
ここでタイトルや秒数、背景画像、チェックマーク、クリックできないようにしていた
スタートボタンなど全てを初期化するようにしています。
記事にしていてわかるけど、記事の言葉がそのままpythonでは1行のコードに
なっているのでpythonはわかりやすいなと改めて思います。
これでポモドーロタイマーのGUIアプリは完成。
ソースはgithubにて。