アナログ ストップウオッチを作ろう

python

FreeSimpleGUIのcode

#アナログストップウオッチver3.py 
import FreeSimpleGUI as sg
import tkinter as tk
import math
import time

sg.theme('BluePurple')

# グローバル変数
window = None
canvas = None
timer_running = False
start_time = None
elapsed_time = 0

def create_window():
    global window, canvas
    layout = [
        [sg.Text('Analog Stopwatch', font=('Helvetica', 24, 'bold'), justification='center', size=(30, 1))],
        [sg.Canvas(key='-CANVAS-', size=(600, 500))],
        [sg.Column([
            [sg.Text('Elapsed Time:', font=('Helvetica', 20, 'bold'), text_color='red', key='-ELAPSED-', justification='center', size=(15, 1)),
            sg.Text('00:00', key='-TIME-', font=('Helvetica', 20, 'bold'), relief=sg.RELIEF_SUNKEN, text_color='blue', justification='center', size=(10, 1))]
        ], justification='center')],
        [sg.Column([
            [sg.Button('Start', size=(10, 2), font=('Helvetica', 14)), 
             sg.Button('Hold', size=(10, 2), font=('Helvetica', 14)), 
             sg.Button('Clear', size=(10, 2), font=('Helvetica', 14)),
             sg.Text('      Ja1fml ver 3.0')],
            [sg.Text()]
            ], justification='center')]
        ]
        
    window = sg.Window('Analog Stopwatch ver 3', layout, finalize=True)
    canvas = window['-CANVAS-'].TKCanvas
    draw_clock()

def draw_clock():
    try:
        global canvas, elapsed_time
        canvas.delete("all")
        center_x, center_y = 300, 250
        radius = 200

        canvas.create_oval(center_x - radius, center_y - radius, center_x + radius, center_y + radius, fill='light blue')
        canvas.create_oval(center_x - 5, center_y - 5, center_x + 5, center_y + 5, fill='black')
        
        for i in range(60):
            angle = math.radians(i * 6 - 90)
            start_x = center_x + (radius - 20) * math.cos(angle)
            start_y = center_y + (radius - 20) * math.sin(angle)
            end_x = center_x + radius * math.cos(angle)
            end_y = center_y + radius * math.sin(angle)
            color = 'red' if i % 5 == 0 else 'black'
            width = 3 if i % 5 == 0 else 1
            canvas.create_line(start_x, start_y, end_x, end_y, fill=color, width=width)

            if i % 5 == 0:
                number_x = center_x + (radius - 30) * math.cos(angle)
                number_y = center_y + (radius - 30) * math.sin(angle)
                canvas.create_text(number_x, number_y, text=str(i), fill='red', font=('Helvetica', 14, 'bold'))

        update_hand()
    except Exception as e:
        sg.popup_error('Error in draw_clock: ', str(e))

def update_hand():
    try:
        global canvas, elapsed_time
        center_x, center_y = 300, 250
        radius = 200
        angle = (elapsed_time / 60) * 360
        angle = math.radians(angle - 90)
        end_x = center_x + radius * math.cos(angle)
        end_y = center_y + radius * math.sin(angle)
        canvas.create_line(center_x, center_y, end_x, end_y, width=4, fill='blue')
    except Exception as e:
        sg.popup_error('Error in update_hand: ', str(e))

def start_timer():
    try:
        global start_time, elapsed_time, timer_running
        start_time = time.time() - elapsed_time
        timer_running = True
    except Exception as e:
        sg.popup_error('Error in start_timer: ', str(e))

def stop_timer():
    try:
        global elapsed_time, start_time, timer_running
        elapsed_time = time.time() - start_time
        timer_running = False
    except Exception as e:
        sg.popup_error('Error in stop_timer: ', str(e))

def clear_timer():
    try:
        global elapsed_time, timer_running
        elapsed_time = 0
        timer_running = False
    except Exception as e:
        sg.popup_error('Error in clear_timer: ', str(e))

def update():
    try:
        global elapsed_time, timer_running
        if timer_running:
            elapsed_time = time.time() - start_time

        hours = int(elapsed_time // 3600)
        minutes = int((elapsed_time % 3600) // 60)
        seconds = int(elapsed_time % 60)

        if hours >= 24:
            hours = 24
            minutes = 0
            seconds = 0
            stop_timer()
            window['-TIME-'].update(f'24:00:00')
        else:
            window['-TIME-'].update(f'{hours:02}:{minutes:02}:{seconds:02}')

        draw_clock()
        canvas.after(100, update)
    except Exception as e:
        sg.popup_error('Error in update: ', str(e))

def run():
    try:
        create_window()
        update()

        while True:
            event, values = window.read(timeout=100)
            if event == sg.WIN_CLOSED:
                break
            elif event == 'Start':
                if not timer_running:
                    start_timer()
            elif event == 'Hold':
                if timer_running:
                    stop_timer()
                elif start_time is not None:
                    start_timer()
            elif event == 'Clear':
                clear_timer()

        window.close()
    except Exception as e:
        sg.popup_error('Error in run: ', str(e))

if __name__ == "__main__":
    run()