コンテンツにスキップ

Pythonアプリ(3):ストップウォッチを作ろう

ストップウォッチを作ろう

ストップウォッチを作ります。スタートボタンを押してからストップボタンを押すまでの秒数を測れるようにします。

秒数を表示する

まず、経過した秒数がラベルに表示される仕組みを作ります。

from tentoapp import *
t = 0
def keika():
global t
t += 1
lb.text = t
app.after(1000, keika)
app = App()
lb = Label(app)
lb.text = "0"
lb.fontsize = 30
lb.pack()
app.after(1000,keika)
app.start()

これを実行すると、一秒ごとに数字がどんどん大きくなっていきます。 fontsize で文字のサイズを大きくしていることも注目です。

tentoapp-03-01.png

コードの解説

app.after(1000,keika)
app.start()

最後から二行目に app.after(1000,keika) があるので、アプリを起動して1秒後にkeikaが呼ばれます。

関数keikaを見てみましょう。

def keika():
global t
t += 1
lb.text = t
app.after(1000, keika)

関数keikaでは、tを1ずつ増やしています。ポイントは関数の最後でまた app.after(1000,keika) と1秒後に自分を呼んでいることです。このため、ずっと1秒間隔でkeikaが実行されます。

スタートボタンとストップボタンを追加する

次に、スタートボタンとストップボタンを追加して、スタートボタンを押したら計測が開始され、ストップボタンで止まるようにします。

from tentoapp import *
t = 0
stop = False
def btnstart():
app.after(1000,keika)
def btnstop():
global stop
stop = True
def keika():
global t, stop
if stop == False:
t += 1
lb.text = t
app.after(1000,keika)
app = App()
lb = Label(app)
lb.text = "0"
lb.fontsize = 30
lb.pack()
b1 = Button(app)
b1.text = "スタート"
b1.fontsize = 30
b1.onclick = btnstart
b1.pack()
b2 = Button(app)
b2.text = "ストップ"
b2.fontsize = 30
b2.onclick = btnstop
b2.pack()
app.start()

tentoapp-03-02.png

コードの解説

stop = False
def btnstart():
app.after(1000,keika)
def btnstop():
global stop
stop = True

スタートボタンとストップボタンを増やしました。それぞれクリックしたときに関数 btnstart()btnstop() が呼び出されます。 これまで app.after(1000,keika) はプログラムの開始時に実行されていましたが、 btnstart() に移されたのでスタートボタンを押さないと開始されなくなりました。 また、ストップボタンを押すと変数stopにTrueを代入します。

def keika():
global t, stop
if stop == False:
t += 1
lb.text = t
app.after(1000,keika)

関数keika()は、変数stopで動作が変わるように変更しています。stopがFalseのときだけ、つまりストップボタンが押される前まで秒数が増えていくようにしています。

やってみよう!

1. 再スタートできるようにしよう ★☆☆

現在は、ストップすると一回アプリを終了しないかぎり再スタートできません。少し変更して、ストップ後にスタートボタンを押すとまた0から秒数を数えるようにしてください。

2. スタートしたらボタンを無効化しよう ★☆☆

今のままだと、スタートボタンをクリックしたあともまだスタートボタンを押せてしまいます。スタートボタンを押したあとはストップするまでもうスタートボタンを押せないようにしよう。

3. 分を表示しよう ★★☆

現在は、60秒を超えても 6162 と増えていきます。これを、 1:11:2 のように分と秒を分けて表示してみよう。

4. 桁をそろえよう ★★☆

0秒 や “1:1” は “00:00” や “01:01” のように、分も秒も二桁で表示するようにしよう。 実現方法は色々あるので、調べてみましょう。例えば、 format() 関数でもできるけど、 str() 関数と zfill() メソッドを使うともっと簡単に作ることができるよ。

5. 1/100秒単位で表示しよう ★★☆

秒数だけでなく、その下の1/100秒単位まで表示しよう。 01:04’90(1分4秒90)のようにして、1/100秒まで表示できるようにします。ただし、秒は60で1分になりますが、1/100秒は100で1秒になることに注意してください。

6. (応用)精度を高めよう ★★★

前の課題のように1/100秒ごとにt += 1でカウントアップした値を使って時間を計算する方法では、実は正確な時間になりません(実際に測ってみてください)。Pythonの timeモジュール を使って time.time() で取得した現在時刻を使うほうが正確な計算ができます。