Be1uga 2025. 5. 29. 09:18

import tkinter as tk
import keyboard
import pyperclip
import time
import datetime
import threading
import os
import csv

csv_file = "timer_log.csv"
start_time = None
daily_total_seconds = 0
timer_running = False

def get_today():
    return datetime.datetime.now().strftime('%Y-%m-%d')

def format_seconds(secs):
    h = secs // 3600
    m = (secs % 3600) // 60
    s = secs % 60
    return f"{h:02}:{m:02}:{s:02}"

def update_daily_total():
    global daily_total_seconds
    daily_total_seconds = 0
    today = get_today()
    if os.path.exists(csv_file):
        with open(csv_file, 'r', encoding='utf-8-sig') as f:
            reader = csv.DictReader(f)
            for row in reader:
                if row['날짜'] == today:
                    try:
                        h, m, s = map(int, row['경과시간'].split(':'))
                        daily_total_seconds += h * 3600 + m * 60 + s
                    except:
                        pass

def write_csv_log(date, start, end, elapsed, total):
    file_exists = os.path.isfile(csv_file)
    with open(csv_file, 'a', newline='', encoding='utf-8-sig') as f:
        writer = csv.writer(f)
        if not file_exists:
            writer.writerow(['날짜', '시작시각', '종료시각', '경과시간', '누적시간'])
        writer.writerow([date, start, end, elapsed, total])

def update_gui_timer():
    if timer_running and start_time:
        elapsed = int(time.time() - start_time)
        elapsed_str = format_seconds(elapsed)
        timer_label.config(text=elapsed_str)
        status_label.config(text="타이머 진행 중")
        root.after(1000, update_gui_timer)

def update_total_label():
    update_daily_total()
    total_str = format_seconds(daily_total_seconds)
    total_label.config(text=f"금일 누적: {total_str}")

def on_f2():
    global start_time, timer_running
    start_time = time.time()
    timer_running = True
    now_str = datetime.datetime.now().strftime('%H:%M:%S')
    pyperclip.copy(f"{now_str} 타이머 시작")
    update_gui_timer()

def on_f4():
    global start_time, timer_running, daily_total_seconds
    if not start_time:
        return

    end_time = time.time()
    elapsed_sec = int(end_time - start_time)
    start_dt = datetime.datetime.fromtimestamp(start_time)
    end_dt = datetime.datetime.fromtimestamp(end_time)

    start_str = start_dt.strftime('%H:%M:%S')
    end_str = end_dt.strftime('%H:%M:%S')
    elapsed_str = format_seconds(elapsed_sec)

    update_daily_total()
    daily_total_seconds += elapsed_sec
    total_str = format_seconds(daily_total_seconds)

    today = get_today()
    message = f"{end_str} 경과: {elapsed_str}, 금일 누적: {total_str}"
    pyperclip.copy(message)
    write_csv_log(today, start_str, end_str, elapsed_str, total_str)

    timer_label.config(text=elapsed_str)
    status_label.config(text="타이머 종료됨")
    update_total_label()

    start_time = None
    timer_running = False

def keyboard_listener():
    keyboard.add_hotkey('F2', on_f2)
    keyboard.add_hotkey('F4', on_f4)
    keyboard.wait()

# GUI 설정
root = tk.Tk()
root.title("타이머")
root.geometry("400x200")
root.configure(bg="#f4f4f4")
root.resizable(False, False)

# 경과 시간 라벨
timer_label = tk.Label(root, text="00:00:00", font=("Helvetica", 48, "bold"), fg="#333", bg="#f4f4f4")
timer_label.pack(pady=(30, 10))

# 상태 라벨 (진행중 / 종료됨 등)
status_label = tk.Label(root, text="F2: 시작 / F4: 종료", font=("Helvetica", 12), fg="#666", bg="#f4f4f4")
status_label.pack()

# 누적 시간 라벨
total_label = tk.Label(root, text="금일 누적: 00:00:00", font=("Helvetica", 12), fg="#999", bg="#f4f4f4")
total_label.pack(pady=(10, 0))

# 초기 누적 시간 로딩
update_total_label()

# 키보드 리스너 쓰레드
threading.Thread(target=keyboard_listener, daemon=True).start()

root.mainloop()
import tkinter as tk
from tkinter import ttk
import pyperclip
import time
import datetime
import threading
import os
import csv

csv_file = "timer_log.csv"
start_time = None
daily_total_seconds = 0
timer_running = False

def get_today():
    return datetime.datetime.now().strftime('%Y-%m-%d')

def format_seconds(secs):
    h = secs // 3600
    m = (secs % 3600) // 60
    s = secs % 60
    return f"{h:02}:{m:02}:{s:02}"

def update_daily_total():
    global daily_total_seconds
    daily_total_seconds = 0
    today = get_today()
    if os.path.exists(csv_file):
        with open(csv_file, 'r', encoding='utf-8-sig') as f:
            reader = csv.DictReader(f)
            for row in reader:
                if row['날짜'] == today:
                    try:
                        h, m, s = map(int, row['경과시간'].split(':'))
                        daily_total_seconds += h * 3600 + m * 60 + s
                    except:
                        pass

def write_csv_log(date, start, end, elapsed, total):
    file_exists = os.path.isfile(csv_file)
    with open(csv_file, 'a', newline='', encoding='utf-8-sig') as f:
        writer = csv.writer(f)
        if not file_exists:
            writer.writerow(['날짜', '시작시각', '종료시각', '경과시간', '누적시간'])
        writer.writerow([date, start, end, elapsed, total])

def update_gui_timer():
    if timer_running and start_time:
        elapsed = int(time.time() - start_time)
        elapsed_str = format_seconds(elapsed)
        timer_label.config(text=elapsed_str)
        status_label.config(text="타이머 진행 중")
        root.after(1000, update_gui_timer)

def update_total_label():
    update_daily_total()
    total_str = format_seconds(daily_total_seconds)
    total_label.config(text=f"누적: {total_str}")

def on_start():
    global start_time, timer_running
    start_time = time.time()
    timer_running = True
    now_str = datetime.datetime.now().strftime('%H:%M:%S')
    pyperclip.copy(f"[시작] {now_str}")
    update_gui_timer()

def on_stop():
    global start_time, timer_running, daily_total_seconds
    if not start_time:
        return

    end_time = time.time()
    elapsed_sec = int(end_time - start_time)
    start_dt = datetime.datetime.fromtimestamp(start_time)
    end_dt = datetime.datetime.fromtimestamp(end_time)

    start_str = start_dt.strftime('%H:%M:%S')
    end_str = end_dt.strftime('%H:%M:%S')
    elapsed_str = format_seconds(elapsed_sec)

    update_daily_total()
    daily_total_seconds += elapsed_sec
    total_str = format_seconds(daily_total_seconds)

    today = get_today()
    write_csv_log(today, start_str, end_str, elapsed_str, total_str)

    timer_label.config(text=elapsed_str)
    status_label.config(text="타이머 종료됨")
    update_total_label()

    pyperclip.copy(f"[종료]\n{end_str}, +{elapsed_str}")

    start_time = None
    timer_running = False

# GUI 설정
root = tk.Tk()
root.title("심플 타이머")
root.geometry("270x145")
root.configure(bg="#f4f4f4")
root.resizable(False, False)

# 스타일 적용
style = ttk.Style()
style.theme_use('default')
style.configure("TButton",
                font=("Helvetica", 10),
                padding=6,
                relief="flat",
                background="#5a9",
                foreground="white")
style.map("TButton",
          background=[('active', '#48a')],
          foreground=[('disabled', '#ccc')])

# 경과 시간 라벨
timer_label = tk.Label(root, text="00:00:00", font=("Helvetica", 28, "bold"), fg="#333", bg="#f4f4f4")
timer_label.pack(pady=(10, 5))

# 상태 라벨
status_label = tk.Label(root, text="출발 / 도착 버튼을 누르세요", font=("Helvetica", 10), fg="#666", bg="#f4f4f4")
status_label.pack()

# 누적 시간 라벨
total_label = tk.Label(root, text="누적: 00:00:00", font=("Helvetica", 10), fg="#999", bg="#f4f4f4")
total_label.pack(pady=(2, 5))

# 버튼 프레임
btn_frame = tk.Frame(root, bg="#f4f4f4")
btn_frame.pack(pady=(5, 0))

start_btn = ttk.Button(btn_frame, text="출발", command=on_start)
start_btn.pack(side="left", padx=5)

stop_btn = ttk.Button(btn_frame, text="도착", command=on_stop)
stop_btn.pack(side="right", padx=5)

# 초기 누적 시간 로딩
update_total_label()

root.mainloop()