前回の記事の続きです。
組み込み関数eval
eval(文字列)を使うと、引数の文字列をPythonの式として解析します。
例えば、文字列の”1+1″をevalの引数にしますと、下のようになります。
1 2 |
a = eval("1+1") print(a) # 2 |
このevalを使用して簡単な電卓を作成してみます。
簡単な電卓のコード
作り方は色々あると思いますが、最低限の機能を持った電卓はこんな感じでしょうか?
ボタンを押すと数字や演算子が「+」で文字列連結され、「=」イコールを押すと先程の文字列をevalの引数にして計算するというものです。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 |
from tkinter import * def func(v): var1.set(var1.get() + v) def clear(): var1.set("") def result(): try: var1.set(eval(var1.get())) except SyntaxError: var1.set("SyntaxError") except ZeroDivisionError: var1.set("ZeroDivisionError") except NameError: var1.set("NameError") root = Tk() # すべてのウィジェットのフォント指定 root.option_add("*Font", "Consolas 14") var1 = StringVar() # 0行目 label = Label(root, textvariable=var1, foreground="#ffffff", background="#000000", anchor=E, height=2) label.grid(row=0, column=0, columnspan=4, sticky="EW") # 1行目 btn_7 = Button(root, text="7", command=lambda: func("7"), width=5, height=2) btn_7.grid(row=1, column=0) btn_8 = Button(root, text="8", command=lambda: func("8"), width=5, height=2) btn_8.grid(row=1, column=1) btn_9 = Button(root, text="9", command=lambda: func("9"), width=5, height=2) btn_9.grid(row=1, column=2) btn_div = Button(root, text="/", command=lambda: func("/"), width=5, height=2) btn_div.grid(row=1, column=3) # 2行目 btn_4 = Button(root, text="4", command=lambda: func("4"), width=5, height=2) btn_4.grid(row=2, column=0) btn_5 = Button(root, text="5", command=lambda: func("5"), width=5, height=2) btn_5.grid(row=2, column=1) btn_6 = Button(root, text="6", command=lambda: func("6"), width=5, height=2) btn_6.grid(row=2, column=2) btn_mul = Button(root, text="*", command=lambda: func("*"), width=5, height=2) btn_mul.grid(row=2, column=3) # 3行目 btn_1 = Button(root, text="1", command=lambda: func("1"), width=5, height=2) btn_1.grid(row=3, column=0) btn_2 = Button(root, text="2", command=lambda: func("2"), width=5, height=2) btn_2.grid(row=3, column=1) btn_3 = Button(root, text="3", command=lambda: func("3"), width=5, height=2) btn_3.grid(row=3, column=2) btn_sub = Button(root, text="-", command=lambda: func("-"), width=5, height=2) btn_sub.grid(row=3, column=3) # 4行目 btn_0 = Button(root, text="0", command=lambda: func("0"), width=5, height=2) btn_0.grid(row=4, column=0) btn_c = Button(root, text="C", command=clear, width=5, height=2) btn_c.grid(row=4, column=1) btn_e = Button(root, text="=", command=result, width=5, height=2) btn_e.grid(row=4, column=2) btn_add = Button(root, text="+", command=lambda: func("+"), width=5, height=2) btn_add.grid(row=4, column=3) root.mainloop() |
4行目、8行目、12行目に関数を作りました。ボタンを押したら、それぞれの関数を呼び出しています。
35行目の赤い部分のcommand=の部分で関数を呼びます。
btn_7 = Button(root, text=”7″, command=lambda: func(“7”), width=5, height=2)
引数が必要な関数の場合、command=の後にlambda式でlambda: func(“7”)と書きます。これはfunc関数に文字列の7を引数にして渡すということです。
77行目のように、引数の必要ない関数を呼ぶには、command=clearとします(関数の最後の”()”はいりません)。これはbtn_cを押すとclear関数を呼ぶという意味です。
28行目のStringVar()は、ウィジェットに変数を関連づけるクラスです。
文字列ならStringVar、数値ならIntVar、浮動小数点ならDoubleVar、ブール型ならBooleanVarを使います。
今回は文字列で使うのでStringVar()を使います。StringVar()のオブジェクトをvar1としました。
31行目のLabelのオプションでtextvariable=var1としています。
textvariableは、StringVarをラベルに関連付けます。変数が変更されると、ラベルテキストが更新されます。
4行目の関数のfuncは、数字のボタンと「+」「-」「*」「/」のボタンで呼びます。
5行目のvar1.set(var1.get() + v)ですが、var1.get()はStringVarに入っている値を取得しています。最初は空です。var1.setはStringVarに値を代入しています。文字列の足し算なので例えば”5″+”5″でも10ではなくて、”55″になります。
8行目のclear関数は、77行目のボタンを押すと呼ばれます。
9行目のvar1.set(“”)は、空の文字列をStringVarに代入しています。
12行目のresult関数は、80行目のボタンが押されると呼ばれます。
14行目のvar1.set(eval(var1.get()))ですが、先程説明したevalが登場します。
evalでvar1.get()の文字列を解析して、その結果をvar1.setしています。
この時、var1.get()の文字列によってはエラーが出ますので、try~exceptで囲んでいます。
考えられるエラーはSyntaxError、ZeroDivisionError、NameErrorなので、書いておきました。
小数点もない不便な電卓ですが、この程度ならば簡単に作成できます。