HOME Python download 書き込む

4. タイマーにボタンをつけよう


1. 初めに

今回は前回作成したタイマーにボタンをつけ、図1に示すようなアプリを作ります。


[図1]

前回作成したタイマーは設定時間を GUI 上で変更できなかったので、それを変更できるようにしました。 また、Start, Stop, Reset ボタンをつけてみました。

まず、Button の作成方法について述べてから、プログラムの説明をします。

2. Button の作成

Button は以下のように作成します。
Tk.Button(master, **options)
最初の引数で親 widget を指定し、キーワード引数を続けます。
以下に主な属性を示します。 Tkinter reference: 5. The Button widget や、 The Tkinter Button Widget も参照してください。
属性 説明
anchor ボタン上のテキストの位置。
bd or borderwidth pixel 単位の縁の幅
bg or background ボタンの背景色
bitmap (テキストの代わりに、)ボタンに表示する bitmap 名
command ボタンを押したときに呼ばれる関数を指定
cursor カーソルがボタンにあるとき、その形を指定
default ボタンの状態の初期値。普通は Tk.NORMAL。押せないようにするには Tk.DISABLED。'state' option で同じことができる。
disabledforeground ボタンが押せない状態のときの文字色
fg or foreground 通常の文字色
font フォント
height テキストの行単位のボタンの高さ。image の時は pixel 単位
image テキストの代わりにボタンに表示するイメージ
justify 数行に渡るテキストのそろえ方。
padx 横の余白
pady 縦の余白
relief 縁の形
state ボタンの状態を指定。デフォルトは NORMAL. ボタンが利かない状態にするには DISABLED を指定。
text ボタン上に表示するテキスト
textvariable ボタン上に表示する Tk.StringVar()
underline 下線をつける文字の位置を指定。デフォルトは -1
width テキストを表示しているときは文字数、イメージを表示しているときは pixel で指定。
wraplength 長いテキストの折り返しの幅を指定。
Label の時と同様に、これらの属性は configure メソッドを使って、 プログラムの実行中に変化させることができます。 また、image の貼り方なども Label と同様です。

3. タイマーにボタンをつける。

早速タイマーを作ってみましょう。 かなりの部分は前回作ったものと同じです。 動作中に不要なボタンを押せないようにするため、こまめに state 属性を変えています。

[code 1](timerb.py)

01:     #! /usr/bin/env python
02:     
03:     """
04:     timerb.py
05:     
06:     June 27, 2005
07:     """
08:     
09:     
10:     import Tkinter as Tk
11:     
12:     
13:     
14:     BLUE = '#99CCFF'
15:     YELLOW = '#FFCC00'
16:     RED = '#FF00FF'
17:     CLOCK = 'meza-bl-2.gif'
18:     
19:     class Frame(Tk.Frame):
20:     
21:         def __init__(self, master=None):
22:             Tk.Frame.__init__(self, master)
23:             
24:             self.echo = Tk.StringVar()
25:             self.m = 3
26:             self.echo_set()
27:             
28:             self.master.title('Alarm')
29:             f_display = Tk.Frame(self, relief=Tk.RIDGE, bd=4)
30:             f_display.pack(fill=Tk.X, expand=1)
31:             
32:             self.image= Tk.PhotoImage(file=CLOCK)
33:             self.icon=Tk.Label(f_display, image=self.image, bg=BLUE)
34:             self.icon.grid(row=0,column=0, rowspan=2)
35:             display = Tk.Label(f_display, textvariable=self.echo, width=5, relief=Tk.SUNKEN, bd=2, anchor = Tk.E, 
36:                                  font=('Helvetica', '24'), bg='white')
37:             display.grid(row=0, column=1, rowspan=2, sticky=Tk.N+Tk.S)
38:             self.b_inc = Tk.Button(f_display, font=('Helvetica', '6'), text='+', command=self.inc_time)
39:             self.b_inc.grid(row=0, column=2, sticky=Tk.W + Tk.E + Tk.S, pady=1)
40:             self.b_dec = Tk.Button(f_display, font=('Helvetica', '6'), text='-', command=self.dec_time)
41:             self.b_dec.grid(row=1, column=2, sticky=Tk.W + Tk.E + Tk.N, pady=1)
42:     
43:             
44:             f_button = Tk.Frame(self)
45:             f_button.pack(pady=2)
46:             self.b_start = Tk.Button(f_button, text='Start', command=self.start)
47:             self.b_stop = Tk.Button(f_button, text='Stop', command=self.stop, state=Tk.DISABLED)
48:             self.b_reset = Tk.Button(f_button, text='Reset', command=self.reset, state=Tk.DISABLED)
49:             self.b_start.pack(side=Tk.LEFT, padx=1)
50:             self.b_stop.pack(side=Tk.LEFT, padx=1)
51:             self.b_reset.pack(side=Tk.LEFT, padx=1)
52:     
53:     
54:         def echo_set(self):
55:             self.timer = 60 * self.m
56:             self.echo.set('%02d:00' % (self.m))
57:             
58:         def inc_time(self):
59:             self.m += 1
60:             self.echo_set()
61:     
62:         def dec_time(self):
63:             self.m -= 1
64:             self.echo_set()
65:     
66:         def start(self):
67:             self.started = True
68:             if 0<self.timer<=20:
69:                 self.icon.configure(bg=YELLOW)
70:             elif(0 >= self.timer):
71:                 self.icon.configure(bg=RED)
72:             self.after(1000, self.counting)
73:             self.b_start.configure(state=Tk.DISABLED)
74:             self.b_stop.configure(state=Tk.NORMAL)
75:             self.b_inc.configure(state=Tk.DISABLED)
76:             self.b_dec.configure(state=Tk.DISABLED)
77:     
78:         def stop(self):
79:             self.icon.configure(bg=BLUE)
80:             self.started = False
81:             self.b_start.configure(state=Tk.NORMAL)
82:             self.b_stop.configure(state=Tk.DISABLED)
83:             self.b_reset.configure(state=Tk.NORMAL)
84:     
85:     
86:         def reset(self):
87:             self.echo_set()
88:             self.b_reset.configure(state=Tk.DISABLED)
89:             self.b_inc.configure(state=Tk.NORMAL)
90:             self.b_dec.configure(state=Tk.NORMAL)
91:     
92:         def counting(self):
93:                 if self.started:
94:                     self.timer -=1
95:                     self.echo.set('%02d:%02d' % (self.timer/60, self.timer%60))
96:                     if self.timer == 20:
97:                         self.icon.configure(bg=YELLOW)
98:     
99:                     if self.timer <= 0:
100:                         self.bell()
101:                         t= -1 * self.timer
102:                         self.icon.configure(bg=RED)
103:                         self.echo.set('-%02d:%02d' % (t/60, t%60))
104:                         self.after(500, self.yellow)
105:                         
106:                     self.after(1000, self.counting)
107:     
108:         def yellow(self):
109:             if self.started:
110:                 self.icon.configure(bg=YELLOW)
111:     
112:     
113:     if __name__ == '__main__':
114:         f = Frame()
115:         f.pack()
116:         f.mainloop()

3.1. 使い方と動作

コマンドラインから
>python timerb.py 
とすると、図1で示した widget があらわれます。 設定時間を増やすときには時間表示の右側の '+' ボタンを、減らすときには '-' ボタンを押します。 設定時間は 1 分単位で増減します。

計測を始めるには 'Start'、止めるには 'Stop'、リセットするには 'Reset' ボタンを押します。 時計アイコンの背景色の変化などは前回と同じです。

3.2. プログラムの簡単な説明

以下に簡単な説明をします。カッコ内の数字はソースコードの行数です。

4. Button から指定できる command について

Tk.Button の command オプションで指定するのは関数へのポインターです。 従って、 引数などは指定できません。 指定される関数は内部変数にアクセスするためのポインター self のみを引数とするものに限られます。

普通に考えれると、これはとても不便で、プログラムが冗長になりがちだと思われるかもしれませんが、 次回に述べる手法を用いることによってこの問題を回避することができます。

7. 終わりに

Tk.Button の使い方は一通り説明できたと思います。

次回は似たような command を効率よく定義するこつについて述べます。