Program学習Python

PythonでTkinerを使ってTimerを作ってみる【その1】

Program学習

最近、Pythonのtkinterライブラリを使用してTimer(タイマーのアプリ)機能を作る機会があったため、その方法についてチュートリアル的に説明できればと思います。

最終的に全5回となります。

第1回:https://syachiku.net/python-timer1/ <-今回
第2回:https://syachiku.net/python-timer2/
第3回:https://syachiku.net/python-timer3/
第4回:https://syachiku.net/python-timer4/
第5回:https://syachiku.net/python-timer5/

PythonでGUIのアプリを作る際には、「Kivy」や「PyQt」選択肢がありますが、一番メジャーなのは「Tkinter」ではないでしょうか。

Tkinterは、「ティーキンター」や「ティーケーインター」と呼ばれ、Window、Mac OSX、Linuxといった主要なOSにも対応しているクロスプラットフォームなGUIライブラリでPythonに標準的に組み込まれているGUIライブラリです。

今回作るTimerの要件

まずは、ざっと今回作るTimerアプリの要件について決めておきたいと思います。

今回は完成形を決めてから作りますが、他のアプリを作るうえでも要件を決めるのは重要です。ただ、完全に完成形は決めずに途中で追加・削除するという柔軟性を持ちながら作りますしょう。

  • Timerで設定できるのは「分」と「秒」とし、それぞれがフォーム入力可能とする
  • ボタンは1つとして、開いたタイミングでは「Start」を表示
  • 「Start」ボタンをクリックするとタイマーが開始され、1秒単位でカウントダウンする
  • 0秒になったらアラートのポップアップメッセージを表示する(今回はTkinerのmesageboxで実装する)
  • 「Start」ボタンを押したらタイマーが開始され、ボタンが「Stop」の表示に切り替わる
  • Stopを押したらタイマーが停止する
  • 残り時間として「分」と「秒」を表示する
  • 上と共に「推定での終わる時刻」を表示する。M/D hh:mm:ss形式とする
  • 「推定での終わる時刻」は1分で随時更新される

Timerを作ってみる(最終的な形)

上の要件を作った最終的な見た目は上のようになります。

Timerを作ってみる(第1回)

それではチュートリアルとして段階的に作っていきます。

まずは初回なので基本的な骨組み(ファイル構成など)から作っていきます。

今回は以下の要件の部分であるフォーム部分とボタンの部分、いわゆる見た目の部分から作っていきます。

  • Timerで設定できるのは「分」と「秒」とし、それぞれがフォーム入力可能とする
  • ボタンは1つとして、開いたタイミングでは「Start」を表示

スクリプトファイルの構成について

はじめにスクリプトの構成について考えます。今回は簡単に3つのファイル構成にしたいと思います。ファイル名と役割は以下の様にします。

  1. main.py → メインファイル(特に処理はなし)
  2. timer_view.py → Timerの見た目部分(Tkinter)を処理します。
  3. timer_main.py → Timerの中身のロジック部分を処理します。

1-1. 見た目部分を作成

いきなりですが、見た目を少し良くしたいのでフォーム部分などに「tkinter.ttk」を使います。

tkinter.ttkはTk 8.5から導入されたもので、ttkは通常のtkinterに比べて各ウィジェットの外観がモダンになり、機能も充実されました。

あまり意識することはないのですが、標準のtkinerを拡張した感じのイメージでよいと思います。最近はttkを使う事が多いのでttkを使っていきます。ただ、オプションの指定方法などがtkinterと違うことがありますので注意してください。

早速、第一回のプログラムを作っていきます。見た目を作るのでmain.pyとtimer_view.pyから作っていきます。timer_main.pyも作りますがとりあえずはClassだけ作ります。

// main.py
import tkinter

from timer_view import TimerView

class Main:
    def __init__(self):
        root = tkinter.Tk()
        TimerView(master=root)
        root.mainloop()

if __name__ == "__main__":
    Main()
// timer_view.py
from tkinter import ttk
from tkinter import *

from timer_main import TimerMain


class TimerView(ttk.LabelFrame):
    def __init__(self, master=None):
        self.timer_main = TimerMain()
        __frame = ttk.LabelFrame(master, text="タイマー")
        __frame.pack(anchor="w", fill="x", expand=True, padx=30, pady=10)

        __label = Label(__frame, text="タイマー入力")
        __label.grid(row=0, column=0)

        __label = Entry(__frame, justify="right", width="8", textvariable="")
        __label.grid(row=0, column=1)

        __label = Label(__frame, text="分")
        __label.grid(row=0, column=2)

        __label = Entry(__frame, justify="right", width="8", textvariable="")
        __label.grid(row=0, column=3)

        __label = Label(__frame, text="秒")
        __label.grid(row=0, column=4)

        __label = Button(__frame, text="Start", command="")
        __label.grid(row=0, column=5)
// timer_main.py
class TimerMain():
    def __init__(self):
        pass

ここまでで実行すると以下の様な画面が表示されるはずです。

1-2. Startボタンを押したときの処理を試す

次のStartボタンが押されたときの処理を作ります。

ただ、いきなりカウントダウンの動作を作るのではなく、まずはボタンがおされた時に処理が動くという部分をprintなどで確認します。

TimerMainに[click_timer_button]メソッドを追加してか、TimerViewのStartボタン部分のcommandを指定します。commandで指定した関数がクリック時に実行されます!

// timer_view.py
(省略)
        __label = Button(__frame, text="Start", command=self.timer_main.click_timer_button)
(省略)

// timer_main.py
class TimerMain():
    def __init__(self):
        pass

    def click_timer_button(self):
        print("Click!!!!")

StartボタンをクリックするとTerminalに「Click!!」と表示されるはずです。

1-3. 残り時間表示部分の作成

ボタンで処理が正しく動きだす、という事が分かったので、とりあえず他の見た目部分も作っていきます。

残り時間や推定終了時間などを下の行に配置していきます。まだ動的に値を変更できないので、暫定的な適当なテキストを表示します。

// timer_view.py
(省略)
        __label = Button(__frame, text="Start", command=self.timer_main.click_timer_button)
        __label.grid(row=0, column=5)

        __label = Label(__frame, text="残時間")
        __label.grid(row=1, column=0)

        __label = Label(__frame, text="<残りの分>")
        __label.grid(row=1, column=1)

        __label = Label(__frame, text="分")
        __label.grid(row=1, column=2)

        __label = Label(__frame, text="<残りの秒>")
        __label.grid(row=1, column=3)

        __label = Label(__frame, text="秒")
        __label.grid(row=1, column=4)

        __label = Label(__frame, text="推定終了時刻:")
        __label.grid(row=1, column=5)

        __label = Label(__frame, text="<推定終了時刻が入る>")
        __label.grid(row=1, column=6)

こんな感じで表示されるはずです。あくまでこれは最終的な画面イメージですが、これは頭にいれておきましょう。

まとめ

今回はまず要件定義を決めて、必要ファイルを作成し、主に見た目の部分(Clickの動作だけは確認した)の部分を作成しました。

まだ最初ですが、あらかじめ決めた要件として以下の黄塗の部分が完成ということになります。。

  • Timerで設定できるのは「分」と「秒」とし、それぞれがフォーム入力可能とする
  • ボタンは1つとして、開いたタイミングでは「Start」を表示
  • 「Start」ボタンをクリックするとタイマーが開始され、1秒単位でカウントダウンする
  • 0秒になったらアラートのポップアップメッセージを表示する(今回はTkinerのmesageboxで実装する)
  • 「Start」ボタンを押したらタイマーが開始され、ボタンが「Stop」の表示に切り替わる
  • 残り時間として「分」と「秒」を表示する
  • Stopを押したらタイマーが停止する
  • 上と共に「推定での終わる時刻」を表示する。M/D hh:mm:ss形式とする
  • 「推定での終わる時刻」は1分で随時更新される

次回からはタイマーで一番重要なカウントダウンのロジック部分に着手していきます。

第1回終了時のGithubコード

以下に保管してますので参考にどうぞ

GitHub - gogoloon/python-timer at Lesson#1
Contribute to gogoloon/python-timer development by creating an account on GitHub.

Pythonのオススメ勉強方法

私がオススメするPython初心者向けの最初に購入すべき書籍は「シリコンバレー一流プログラマーが教える Pythonプロフェッショナル大全です。

シリコンバレー一流プログラマーが教える Pythonプロフェッショナル大全

この書籍は実際にシリコンバレーの一流エンジニアとして活躍している酒井潤さんが書いた本です。

内容も初心者から上級者までまとめられており、各Lessonも長すぎずに分かりやすくまとめられているので、初心者の方にもおすすめです。

シリコンバレー一流プログラマーが教える Pythonプロフェッショナル大全

今回は以上となります。

コメント