今回はpythonで、簡易的な電卓アプリを作っていこうと思います。
電卓アプリは標準で入っていると思いますが、まあ、tkinterの学習とでも思いましょう。
初心者の方にも分かりやすいようにコードはできるだけ短くしたつもりです。
それでは、作っていきましょう!
ちなみにこんなのを作ります。
まずはライブラリをインポートしましょう。
今回はtkinterをtkとして読み込みます。
Tkinterは、PythonでGUIアプリケーションを作成するための標準ライブラリです。
class CalculatorApp:
def __init__(self, root):
self.root = root
self.root.title("電卓")
self.result_var = tk.StringVar()
classというのは、このアプリ自体だと思っとけば大丈夫です。
__init__は、クラスのインスタンスが作成される際に自動的に呼び出されるコンストラクタメソッドというものです。クラスのインスタンスを初期化するための処理を行うのに使用されます。
簡単にいえば、一番最初に実行される関数ってことです。
selfというのは、クラスのメソッド内でそのクラスのインスタンス自体を指す特別な変数です。
__init__の引数にとりあえず書いとくという認識でいいと思います。
rootは通常、Tkinterを使用してGUIアプリケーションを作成する際にメインウィンドウを指す変数です。
これを生成することで、ボタンやテキストなどのウィジェットを操作できるようになります。
最後のself.result_varは、計算表示部分のテキストや計算結果などの値を管理する変数です。
def create_ui(self):
entry = tk.Entry(self.root, textvariable=self.result_var,
font=("Helvetica", 24), bd=10, insertwidth=1, width=20,
justify='right')
entry.grid(row=0, column=0, columnspan=4)
buttons = [
('C', 'B', '(', ')'),
('7', '8', '9', '/'),
('4', '5', '6', '*'),
('1', '2', '3', '-'),
('.', '0', '=', '+'),
]
for row, button_row in enumerate(buttons, start=1):
for col, text in enumerate(button_row):
button = tk.Button(self.root, text=text, font=("Helvetica", 18),
width=3,command=lambda t=text: self.on_button_click(t))
button.grid(row=row, column=col, padx=10, pady=10)
create_uiは、その名の通り、UIを作る関数です。
entryは計算を行うテキストボックスの部分です。大きさやフォント、右側から入力することを設定してます。また、中のテキストをresult_varに関連付けています。
entry.gridでは、何行目(row)、何列目(column)、複数の列をまたがる場合何列分(columnspin)に配置するかについて設定します。複数の行をまたがる場合はrowspanを設定する必要があります。計算表示部分は一番上の行で、ボタンのある列分の列をまたがりたいのでこのようになっています。
buttonsも、その名の通りボタン配置を宣言してます。
ボタンがある列は('C', 'B', '(', ')')の4列のことです。
そのあとのfor文では、UIにボタンとそのテキストを配置しています。1行目の1列目、2列目、...2行目の1列目...というように、行と列の分(要するにボタンの数)だけ繰り返されます。
buttonで、UIにボタンを配置します。
command=lambda t=text: self.on_button_click(t)というのは、ボタンを押されたときの処理なので、後ほど説明します。
button.gridはさっきと同じで行や列。
UIは最初に読み込みたいので、次の文を__init__に追加しましょう。
self.create_ui()
計算する関数を作ります。
def on_button_click(self, value):
if value == '=':
try:
result = str(eval(self.result_var.get()))
self.result_var.set(result)
except:
self.result_var.set("Error")
elif value == 'C':
self.result_var.set("")
elif value == 'B':
current_text = self.result_var.get()
new_text = current_text[:-1]
self.result_var.set(new_text)
else:
current_text = self.result_var.get()
new_text = current_text + value
self.result_var.set(new_text)
さっきbuttonであったself.on_button_click(t)は、この関数のことです。buttonのとこでt=textと入力したので、valueというのは、押したボタンの中のテキストのことです。
もし押されたボタンが'='だったらresult_varに書かれてた式を計算し、文字列に変換したものをresultという変数に代入。それをresult_varに反映させる。もしエラーが起こったら、Errorという文字列を反映させる。
また、押されたボタンが'C'ならresult_varに''(何もない状態)を反映させ、
押されたボタンが'B'なら、current_textにresult_varに書かれてた式を代入し、new_textで1文字減らした式にする。そして、new_textをresult_varに反映させる。
押されたボタンがそれら以外なら、もとに式にボタンのテキストを追加し、result_varに反映させる。
という意味になります。
ここまできたらもうすぐ完成です。
それでは最後の記述にいきましょう!
if __name__ == "__main__":
root = tk.Tk()
app = CalculatorApp(root)
root.mainloop()
スクリプトが実行されたら(__name__が__main__という値を持つと)
ウィンドウを作成、
appのインスタンスを生成してUIなどを初期化。
あとは処理をループさせるmainloop()を書いて完成!
では実行してみましょう。
整数の四則演算はちゃんと動作しました。が、小数の計算に不具合がありました。
このように小数の乗法などでは少しおかしな結果が出ました。
なんとかならないか調べてみましたが、どうやらdecimalモジュールというものを使う必要があるようで、少々めんどくさいのでやめておきます。
ですが小数の加減法はほぼ正確にできるようです。
ちなみに'*'を2回入力('**')したらべき乗の計算もできます。
なので、2**0.5と入力したら√2を求めることもできます。
では最後に全体のコードを載せて終わります。
import tkinter as tk
class CalculatorApp:
def __init__(self, root):
self.root = root
self.root.title("電卓")
self.result_var = tk.StringVar()
self.create_ui()
def create_ui(self):
entry = tk.Entry(self.root, textvariable=self.result_var,
font=("Helvetica", 24), bd=10, insertwidth=1, width=20, justify='right')
entry.grid(row=0, column=0, columnspan=4)
buttons = [
('C', 'B', '(', ')'),
('7', '8', '9', '/'),
('4', '5', '6', '*'),
('1', '2', '3', '-'),
('.', '0', '=', '+'),
]
for row, button_row in enumerate(buttons, start=1):
for col, text in enumerate(button_row):
button = tk.Button(self.root, text=text, font=("Helvetica", 18),width=3,
command=lambda t=text: self.on_button_click(t))
button.grid(row=row, column=col, padx=10, pady=10)
def on_button_click(self, value):
if value == '=':
try:
result = str(eval(self.result_var.get()))
self.result_var.set(result)
except:
self.result_var.set("Error")
elif value == 'C':
self.result_var.set("")
elif value == 'B':
current_text = self.result_var.get()
new_text = current_text[:-1]
self.result_var.set(new_text)
else:
current_text = self.result_var.get()
new_text = current_text + value
self.result_var.set(new_text)
if __name__ == "__main__":
root = tk.Tk()
app = CalculatorApp(root)
root.mainloop()
以上、Pythonで簡易的な電卓を作ってみよう!でした。