完成イメージ
コード全文
import tkinter as tk def calculate(): try: result = eval(entry.get()) entry.delete(0, tk.END) # 結果を表示する前にエントリーボックスをクリア entry.insert(tk.END, str(result)) # 結果を表示 except Exception as e: entry.delete(0, tk.END) # エラーがあればエントリーボックスをクリア entry.insert(tk.END, "エラー") def clear(): entry.delete(0, tk.END) # メインウィンドウの作成 root = tk.Tk() root.title("計算機") # エントリーボックス entry = tk.Entry(root, width=20) entry.grid(row=0, column=0, columnspan=4, sticky="nsew") # ボタンのレイアウト buttons = [ '7', '8', '9', '/', '4', '5', '6', '*', '1', '2', '3', '-', '0', 'C', '=', '+' ] # ボタンの作成と配置 row_val = 1 col_val = 0 for button in buttons: action = lambda x=button: entry.insert(tk.END, x) # イコールボタンに関数の割り当て if col_val == 2 and row_val == 4: tk.Button(root, text='=', width=5, height=2, command=calculate).grid(row=row_val, column=col_val, sticky="nsew") elif col_val == 1 and row_val == 4: tk.Button(root, text='C', width=5, height=2, command=clear).grid(row=row_val, column=col_val, sticky="nsew") else: tk.Button(root, text=button, width=5, height=2, command=action).grid(row=row_val, column=col_val, sticky="nsew") col_val += 1 if col_val > 3: col_val = 0 row_val += 1 # 結果表示用のラベル result = tk.StringVar() result.set("") result_label = tk.Label(root, textvariable=result) result_label.grid(row=row_val, column=0, columnspan=4, sticky="nsew") # グリッドの設定 for i in range(5): root.grid_rowconfigure(i, weight=1) root.grid_columnconfigure(i, weight=1) root.mainloop()
コード解説
ウィンドウ、ウィジェットの作成、配置
# メインウィンドウの作成 root = tk.Tk() root.title("計算機") # エントリーボックス entry = tk.Entry(root, width=20) entry.grid(row=0, column=0, columnspan=4, sticky="nsew") # ボタンのレイアウト buttons = [ '7', '8', '9', '/', '4', '5', '6', '*', '1', '2', '3', '-', '0', 'C', '=', '+' ] # ボタンの作成と配置 row_val = 1 col_val = 0 for button in buttons: action = lambda x=button: entry.insert(tk.END, x) if col_val == 2 and row_val == 4: # イコールボタンに関数の割り当て tk.Button(root, text='=', width=5, height=2, command=calculate).grid(row=row_val, column=col_val, sticky="nsew") elif col_val == 1 and row_val == 4: # クリアボタンに関数の割り当て tk.Button(root, text='C', width=5, height=2, command=clear).grid(row=row_val, column=col_val, sticky="nsew") else: tk.Button(root, text=button, width=5, height=2, command=action).grid(row=row_val, column=col_val, sticky="nsew") col_val += 1 if col_val > 3: col_val = 0 row_val += 1 # 結果表示用のラベル result = tk.StringVar() result.set("") result_label = tk.Label(root, textvariable=result) result_label.grid(row=row_val, column=0, columnspan=4, sticky="nsew")
いくつかポイントとなる部分をピックアップして解説します。
〇関数の割り当て
数字や+, -, *, / などの演算子は command=actionの部分で関数を割り当てています。lambda を使い、無名関数を定義して、action に代入しています。
entry.insert(文字の位置、セットしたい文字列)
tk.End # 文字列の最後
= と C には、それぞれ計算結果を出力するための calculate 関数とエントリーをクリアするための clear 関数を去り当てます。これらの関数の中身は後述します。
〇grid に配置
for button in buttons: を使い、繰り返し処理を行い、すべてのボタンを配置していきます。buttons の要素が 4 × 4 =16 個あるので、16 回繰り返されます。
tk.Button(root, text=button, width=5, height=2, command=action).grid(row=row_val, column=col_val, sticky="nsew")
.grid(row=行, column=列, sticky="nsew") で何行何列に配置するか指定します。sticky はウィジェットを寄せる方向を指定します。今回は nsew(北南東西すべて)なので、grid の拡大・縮小に合わせてボタンも拡大・縮小されます。
〇結果の出力、StringVar()
result = tk.StringVar() #stringのウィジェット変数を取得 result.set("") result_label = tk.Label(root, textvariable=result) #Labelにウィジェット変数を割り当て
StringVar() はウィジェット変数と呼ばれるものになります。
ウィジェット変数(制御変数)
ウィジェット変数はウィジェットと連動する変数のことです。ウィジェットに設定することで、ウィジェットの表示を動的に変化させたり、入力を動的に取得したりすることができます。
tkinter には次のウィジェット変数が用意されています。
- StringVar():string
- IntVar():int
- DoubleVar():double
- BooleanVar():bool
今回の電卓の作成では、結果の出力に使用しています。
result = tk.StringVar() #stringのウィジェット変数を取得 result.set("") result_label = tk.Label(root, textvariable=result) #Labelにウィジェット変数を割り当て