이번에 pomodoro 타이머를 만들어보자

Pomodoro는 일단 25분 집중 후 5분 휴식을 하는 것인데 이것을 통해 시간관리를 진행할때가 많다

갑자기 타이머를 만드는 이유는 tictactoe를 GUI로 전환하기 전 GUI에 대한 이해도를 높이기 위한 전초작업 정도로 생각하면 편리할 것 같다.

먼저 GUI로는 tkinter를 이용할 것이고 타이머를 제작해보면 어느정도 tkinter에 대해 전반적으로 알 수 있다고 생각한다.

tkinter를 배우는 순서는 gird 등등 배치를 배우고 나면 버튼 매칭하기 버튼에 트리거 되는 함수 짜기 마지막으로 window.after 이런 식으로 생각하면 편할 것이다.

from tkinter import *
from tkinter import messagebox
import math
import itertools
# ---------------------------- CONSTANTS ------------------------------- #
PINK = "#e2979c"
RED = "#e7305b"
GREEN = "#9bdeac"
YELLOW = "#f7f5dd"
FONT_NAME = "Courier"
WORK_MIN = 25
SHORT_BREAK_MIN = 5
LONG_BREAK_MIN = 20
reps = 0
timer = None
pause = False
toggle_pause_unpause = itertools.cycle(["pause","unpause"])
toggle_start_reset = itertools.cycle(["Reset","Start"])
# ---------------------------- TIMER RESET ------------------------------- # 
def reset_timer():
    window.after_cancel(timer)
    logo.config(text='Timer',fg=GREEN)
    canvas.itemconfig(timer_text,text="00:00")
    check.config(text='')
    global  reps
    reps = 0


# ---------------------------- TIMER MECHANISM ------------------------------- # 
def start_timer():
    global reps
    reps += 1
    work_sec = WORK_MIN* 60
    short_break_sec = SHORT_BREAK_MIN *60
    long_break_sec = LONG_BREAK_MIN* 60
    if reps ==8:
        count_down(long_break_sec)#long
        logo.config(text='Finish',fg=RED)
        ask = messagebox.askquestion(title="Alarm", message="Finish")
        reset_timer()
    elif reps % 2 ==0:
        count_down(short_break_sec)#short_break_sec
        logo.config(text='Break',fg=PINK)
        on_pause_unpause_button_clicked()
        ask = messagebox.askquestion(title="Alarm", message="Take a break")
        if ask == 'yes':
            on_pause_unpause_button_clicked()

    elif reps ==1:
        count_down(work_sec)#work_sec
        logo.config(text='Work',fg=GREEN)
    else:
        count_down(work_sec)#work_sec
        logo.config(text='Work',fg=GREEN)
        on_pause_unpause_button_clicked()
        ask = messagebox.askquestion(title="Alarm", message="Go back to work")
        if ask == 'yes':
            on_pause_unpause_button_clicked()


def on_pause_unpause_button_clicked():
    action = next(toggle_pause_unpause)
    global pause
    if action == 'pause':
        pause = True
    elif action == 'unpause':
        pause = False

def toggle():
    start_reset_now = next(toggle_start_reset)
    start_button.config(text=start_reset_now)
    if start_reset_now == 'Reset':
        start_timer()
    elif start_reset_now == 'Start':
        reset_timer()


# ---------------------------- COUNTDOWN MECHANISM ------------------------------- # 
def count_down(count):
    global reps
    count_min = math.floor(count / 60)
    count_sec = count % 60
    if count_sec < 10:
        count_sec = '0'+str(count_sec)
    if count_sec ==0:
        count_sec ='00'

    canvas.itemconfig(timer_text,text = f"{count_min}:{count_sec}")
    if count >0:
        global timer
        if pause == False:
            timer = window.after(1000,count_down,count - 1)
        elif pause == True:
            timer = window.after(0,count_down,count)
    else:
        start_timer()
        check_time = math.floor((reps-1) / 2)
        check.config(text = '✓'*check_time)



# ---------------------------- UI SETUP ------------------------------- #


window = Tk()
window.title('Pomodoro')
window.wm_attributes("-topmost", 1)
window.config(padx=10,pady=10,bg=YELLOW)

#canvas
canvas = Canvas(width=100,height=112,bg=YELLOW, highlightthickness=0)
tomato_img = PhotoImage(file='tomato.png')
canvas.create_image(50,56,image=tomato_img)
timer_text = canvas.create_text(50,70,text='00:00',fill='white',font=(FONT_NAME,22,'bold'))
canvas.grid(column=1,row=1)



#label
logo = Label(text='Timer',fg=GREEN,bg=YELLOW,font=(FONT_NAME,27,'bold'))
logo.grid(column=1,row=0)

check = Label(bg=YELLOW,fg=GREEN,font=(FONT_NAME,11))
check.grid(column=1,row=3)
#button
start_button = Button(text="Start",command=toggle,highlightthickness=0)
start_button.grid(column=0,row=2)


pause_button = Button(text='pause',command=on_pause_unpause_button_clicked,highlightthickness=0)
pause_button.grid(column=2,row=2)



window.mainloop()

거두절미하고 포모도르-타이머를 클릭하면 쉽게 어떤 식으로 작동하는지 테스트 해볼 수 있다.

각각의 타이머가 시간이 다 끝나면 메시지 박스가 나오는 식이고 크기를 작게하고 바탕화면 항상 최상위에 위치하도록 하여서 시간확인이 용이하게 만들었다. 스타트 버튼을 누르면 리셋버튼으로 바뀌어서 혹시라도 있을 다중시작이 안되게 하였고 리셋 버튼을 누르면 리셋 후 다시 스타트버튼으로 바뀌게 되어있다.

그렇다면 이것을 매일 실행할때 어떻게 하면 바탕화면에서 exe파일로 바로 시작할 수 있을까? 정답은 pyinstaller다

cmd창이나 terminal에서

pyinstaller -w -F --icon=icon.ico -n pomodoro_timer.exe main.py

-w 윈도우콘솔 표시안함 (gui이기 때문에 굳이 필요없어서 표시안함)

-F exe파일 한개만 생성

-icon 아이콘

-n 파일 이름 난 pomodoro_timer로 했음

마지막에 main.py는 exe화할 파이썬 파일이다.

이렇게 하면 직접 exe파일로 바탕화면에서 킬 수 있다. 이미지도 pyinstaller안에 넣어주면 다른 사람들도 실행이 가능하다.