1

tkinter を使用して簡単な電卓アプリを作成しようとしていますが、以下のコードを実行するたびにエラー メッセージが表示されます。

Traceback (most recent call last):
  File "C:\Python33\Lib\site-packages\pythonwin\pywin\framework\scriptutils.py", line 326, in RunScript
    exec(codeObject, __main__.__dict__)
  File "C:\Users\csp\Python\Calculator App.py", line 17, in <module>
    solved = eval(expression)
  File "<string>", line 0

   ^
SyntaxError: unexpected EOF while parsing

コード:

from tkinter import *
tk = Tk()
tk.title('Calculator')
inp = Entry(tk,text="Enter Expression Here",width=20)
inp.pack()
exit = False
def exitbtn():
    global exit
    exit = True
    return exit
btn = Button(tk,text="Quit?",command=exitbtn)
btn.pack
canvas = Canvas(tk,width=200,height=200)
canvas.pack()
while not exit:
    expression = inp.get()
    solved = eval(expression)
    canvas.create_text(100,100,text=expression,font=('Times', 15))
    canvas.create_text(100,150,text=solved,font=('Times', 15))
    if exit == True:
        break
tk.destroy()

私はPythonが初めてで、「solved = eval(expression)」行が機能しない理由を理解していません。助けてください

4

1 に答える 1

2

したがって、 が機能しない理由evalは、プログラムを最初に起動したときにexpressionが単なる空の文字列であるためです。Python シェルに移動して と入力するとeval('')、同じエラーが表示されます。

expression1 つの解決策は、 が空の文字列かどうかを確認し、次のようにすることです。

expression = inp.get()
if expression != '':
    solved = eval(expression)
else:
    solved = '?'

ただし、この修正を適用した後でも、別の理由でプログラムが機能しなくなります。主な理由は、あなたが決して電話をかけないtk.mainloop()(またはそれが何と呼ばれても) ため、ウィンドウが表示されないことです。

これはwhileループが原因です。あなたがやりたかったことは、常に入力フィールドをチェックし、実行後に新しい入力を取得するたびにキャンバスを更新することでしたeval

ただし、GUI プログラムは一般にそのようには機能せず、作成中に別の考え方とアプローチが必要になります。プログラムの状態をチェックして更新するループを記述する代わりに、プログラムの状態が変化するたびに自動的に呼び出される関数 (イベントと呼ばれます) を記述します。最初は少し後ろ向きに感じるかもしれませんが、時間が経つにつれて、コードがよりクリーンになり、管理しやすくなります。

実際には、プログラムの一部、つまりexitbtn関数でこれを既に行っています。while次に、ループを同様の関数に変換し、それをEntryオブジェクトにバインドする必要があります。

編集:

必要なことを行うコードの例を次に示します。

import sys
from tkinter import *


# Create the GUI
tk = Tk()
tk.title('Calculator')

inp = Entry(tk, text="Enter Expression Here", width=20)
inp.pack()

btn = Button(tk, text="Quit?")
btn.pack()

canvas = Canvas(tk, width=200, height=200)
canvas.pack()


# Create callback functions
def end_program(event):
    '''Destroys the window and ends the program without needing
    to use global variables or a while loop'''
    tk.destroy()
    sys.exit() # Automatically ends any Python program

def update_canvas(event):
    '''Gets the input, tries to eval it, and displays it to the canvas'''
    expression = inp.get()
    try:
        solved = eval(expression)
    except SyntaxError: 
        # The expression wasn't valid, (for example, try typing in "2 +")
        # so I defaulted to something else.
        solved = '??'

    canvas.delete('all') # remove old text to avoid overlapping
    canvas.create_text(100, 100, text=expression,font=('Times', 15))
    canvas.create_text(100, 150, text=solved,font=('Times', 15))


# Bind callbacks to GUI elements
btn.bind('<Button-1>', end_program)
inp.bind('<KeyRelease>', update_canvas)


# Run the program
tk.mainloop()

注意すべき点:

  • inpキャンバスをチェックして書き込むためのコードを関数に移動し、ループupdate_canvasを取り除きました。while
  • この関数は、オブジェクト (イベント) update_canvasの入力中に誰かがキーを放すたびに自動的に呼び出されます。inp<KeyRelease>
    • これにより、いくつかの問題が発生する可能性があります。これはupdate_canvas、ユーザーが電卓にテキストを入力している間に関数が呼び出されることを意味します。たとえば、ユーザーが次のように入力するとどうなる2 + 2 *でしょうか? これは完全な式ではないため、 で解析できませんeval
    • これを解決するevalために、間違った入力がプログラムを台無しにするのを防ぐために、try-except でラップしました。
  • 同様に、誰かがオブジェクト (イベント)end_programを左クリックするたびに呼び出されます。btn<Button-1>
于 2013-03-29T15:51:12.520 に答える