Pythonで作るシンプルなストップウォッチアプリ:TkinterとPAGEでGUI開発に挑戦!

プログラミング学習中の方へ!今回は、PythonのGUIライブラリTkinterとGUIデザインツールPAGEを使って、シンプルなストップウォッチアプリを作成する方法をご紹介します。

なぜストップウォッチアプリを作るのか?

GUIアプリ開発は、プログラミングの応用範囲を広げ、実用的なスキルを身につけるのに最適です。ストップウォッチアプリは、基本的なGUI操作やタイマー機能を学ぶのにぴったりのプロジェクトです。

完成イメージ

作成するストップウォッチアプリは、以下の機能を持ちます。

  • 現在時刻の表示
  • ストップウォッチ機能(スタート/ストップ)
  • 経過時間の表示(ミリ秒単位)

必要なもの

PAGEの解説やインストールについては以下を参照ください。

コード解説

アプリは2つのPythonファイルで構成されています。

stopwatch.py (メインGUI)

#! /usr/bin/env python3
#  -*- coding: utf-8 -*-
#
# GUI module generated by PAGE version 8.0
#  in conjunction with Tcl version 8.6
#    Nov 02, 2024 03:26:09 PM JST  platform: Windows NT

import sys
import tkinter as tk
import tkinter.ttk as ttk
from tkinter.constants import *
import os.path

_location = os.path.dirname(__file__)

import stopwatch_support

_bgcolor = '#d9d9d9'
_fgcolor = '#000000'
_tabfg1 = 'black' 
_tabfg2 = 'white' 
_bgmode = 'light' 
_tabbg1 = '#d9d9d9' 
_tabbg2 = 'gray40' 

_style_code_ran = 0
def _style_code():
    global _style_code_ran
    if _style_code_ran: return        
    try: stopwatch_support.root.tk.call('source',
                os.path.join(_location, 'themes', 'default.tcl'))
    except: pass
    style = ttk.Style()
    style.theme_use('default')
    style.configure('.', font = "TkDefaultFont")
    if sys.platform == "win32":
       style.theme_use('winnative')    
    _style_code_ran = 1

class Toplevel1:
    def __init__(self, top=None):
        '''This class configures and populates the toplevel window.
           top is the toplevel containing window.'''

        top.geometry("344x181+660+210")
        top.minsize(120, 1)
        top.maxsize(3844, 1061)
        top.resizable(1,  1)
        top.title("Toplevel 0")
        top.configure(background="#d9d9d9")
        top.configure(highlightbackground="#d9d9d9")
        top.configure(highlightcolor="#000000")

        self.top = top

        _style_code()
        self.TButton1 = ttk.Button(self.top)
        self.TButton1.place(relx=0.291, rely=0.773, height=26, width=155)
        self.TButton1.configure(command=stopwatch_support.start_stop_buton_on_click)
        self.TButton1.configure(text='''Start''')
        self.TButton1.configure(compound='left')

        self.TLabel1 = ttk.Label(self.top)
        self.TLabel1.place(relx=0.087, rely=0.11, height=45, width=50)
        self.TLabel1.configure(font="-family {Yu Gothic UI} -size 18")
        self.TLabel1.configure(relief="flat")
        self.TLabel1.configure(text='''時刻''')
        self.TLabel1.configure(compound='left')

        self.TEntry1 = ttk.Entry(self.top)
        self.TEntry1.place(relx=0.291, rely=0.11, relheight=0.215
                , relwidth=0.564)
        self.TEntry1.configure(font="-family {Yu Gothic UI} -size 18")
        self.TEntry1.configure(justify='center')
        self.TEntry1.configure(cursor="ibeam")

        self.TEntry2 = ttk.Entry(self.top)
        self.TEntry2.place(relx=0.07, rely=0.442, relheight=0.271
                , relwidth=0.855)
        self.TEntry2.configure(font="-family {Yu Gothic UI} -size 18")
        self.TEntry2.configure(justify='center')
        self.TEntry2.configure(cursor="fleur")

def start_up():
    stopwatch_support.main()

if __name__ == '__main__':
    stopwatch_support.main()

stopwatch_support.py (ストップウォッチ機能)

#! /usr/bin/env python3
#  -*- coding: utf-8 -*-
#
# Support module generated by PAGE version 8.0
#  in conjunction with Tcl version 8.6
#    Nov 02, 2024 03:02:52 PM JST  platform: Windows NT

import sys
import tkinter as tk
import tkinter.ttk as ttk
from tkinter.constants import *

import stopwatch
import time

clock_entry = None
time_entry = None
startstop_btn = None
Start_time = None
End_time = None

def main(*args):
    '''Main entry point for the application.'''
    global root
    global clock_entry
    global time_entry
    global startstop_btn
    
    root = tk.Tk()
    root.protocol( 'WM_DELETE_WINDOW' , root.destroy)
    # Creates a toplevel widget.
    global _top1, _w1
    _top1 = root
    _w1 = stopwatch.Toplevel1(_top1)
    clock_entry = _w1.TEntry1
    clock_entry.after(1000,cycle_func)
    time_entry = _w1.TEntry2
    startstop_btn = _w1.TButton1
    
    init_timer()
    update_clock()  # 初回の時刻をセット
    root.mainloop()

def get_time_string():
    return time.strftime('%H:%M:%S')

def update_clock():
    clock_entry.delete(0, tk.END)  # 全てのテキストを削除
    clock_entry.insert(0,get_time_string())

def init_timer():
    time_entry.delete(0, tk.END)  # 全てのテキストを削除
    time_entry.insert(0,"00:00:00.000")
    
def update_timer():
    elapsed_time = End_time - Start_time
   
    # 経過時間をフォーマットして文字列に変換
    milliseconds = int((elapsed_time - int(elapsed_time)) * 1000)
    minutes, seconds = divmod(int(elapsed_time), 60)
    hours, minutes = divmod(minutes, 60)
    formatted_time = f"{int(hours):02}:{int(minutes):02}:{int(seconds):02}.{milliseconds:03}"

    time_entry.delete(0, tk.END)  # 全てのテキストを削除
    time_entry.insert(0, formatted_time)
    
def start_stop_buton_on_click(*args):
    global startstop_btn
    global Start_time
    global End_time
    
    if startstop_btn['text']=="Start":
        startstop_btn['text']="Stop"
        init_timer()
        Start_time = time.time()
        End_time  = Start_time
        startstop_btn.after(10,cycle_timer_func)
    else:
        startstop_btn['text']="Start"
        End_time  = time.time()
        update_timer()
        
def cycle_timer_func():
    global startstop_btn
    global End_time
    if startstop_btn['text']=="Stop":
        End_time  = time.time()
        update_timer()
        startstop_btn.after(10,cycle_timer_func)
            
def cycle_func():
    update_clock()  # 時刻のアップデート
    clock_entry.after(1000,cycle_func)


if __name__ == '__main__':
    stopwatch.start_up()

解説

  • stopwatch.pyはGUIのレイアウトとウィジェットの配置を定義しています。
  • stopwatch_support.pyはストップウォッチの機能を実装しています。

実行方法

ターミナルでpython stopwatch.pyを実行します。

以下のような画面が出力されます。
Startボタンを押せばカウント開始されます。

まとめ

このブログ記事では、TkinterとPAGEを使ってシンプルなストップウォッチアプリを作成する方法を紹介しました。GUIアプリ開発の基礎を学ぶのに最適なプロジェクトです。ぜひ、実際にコードを実行して、アプリの動作を確認してみてください。

この記事が、あなたの役に立てば幸いです!

にいやん

出身 : 関西 居住区 : 関西 職業 : 組み込み機器エンジニア (エンジニア歴13年) 年齢 : 38歳(2022年11月現在) 最近 業務の効率化で噂もありPython言語に興味を持ち勉強しています。 そこで学んだことを記事にして皆さんとシェアさせていただければと思いブログをはじめました!! 興味ある記事があれば皆さん見ていってください!! にほんブログ村