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