【问题标题】:Python Tkinter Calculator wont evaluate text from entry widgetPython Tkinter Calculator 不会评估来自条目小部件的文本
【发布时间】:2013-03-20 07:35:26
【问题描述】:

我正在尝试使用 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)”行不起作用。请帮忙

【问题讨论】:

    标签: python tkinter eval calculator


    【解决方案1】:

    所以,eval 不起作用的原因是,当您第一次启动程序时,expression 只是一个空字符串。如果你进入 python shell,输入eval(''),你会看到同样的错误出现。

    一种解决方案是检查expression 是否为空字符串,然后执行以下操作:

    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 循环。
    • 只要有人在输入inp 对象(&lt;KeyRelease&gt; 事件)时松开按键,就会自动调用update_canvas 函数。
      • 这可能会导致一些问题——这意味着您的update_canvas 函数将在用户在您的计算器中输入文本的过程中被调用。例如,如果用户输入2 + 2 * 会怎样?这不是一个完整的表达式,所以无法被eval解析。
      • 为了解决这个问题,我只是将 eval 包装在一个 try-except 中,以防止任何错误的输入破坏程序。
    • 同样,只要有人左键单击btn 对象(&lt;Button-1&gt; 事件),就会调用end_program。

    【讨论】:

    • 什么意思?你有一个简单的例子可以让我更好地理解吗?
    • 你在哪里定义了 tk.mainloop?
    • @user2155059 你什么意思?我在文件底部调用它。
    • 你在哪里告诉 tk mainloop 当你调用它时要做什么就是我的意思。
    • @user2155059 这就是我将回调绑定到 GUI 元素(btn.bind 和 inp.bind)的地方。基本上,当我调用这两个函数时,我告诉tk.mainloop:“如果我单击按钮,则运行end_program 函数。如果我在输入框中释放一个键,则调用update_canvas 按钮。同时,只是等待发生一些事情”。这基本上就是 GUI 编程通常的完成方式:将函数绑定到事件,然后调用 mainloop 函数(库提供),它会自动处理这些事情。
    猜你喜欢
    • 2017-11-23
    • 2014-04-16
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-10-06
    相关资源
    最近更新 更多