我正在尝试使用GUI创建一个简单的计算器。所以到目前为止,我只有按钮和输入框设置,但是我不知道如何在它们上显示文本。因此,当前,“等式”等于0。我要做的是当用户按下等号按钮时,它将在输入框(称为输入框)上显示已求解的方程式。我要怎么做才能将等式显示回输入框?

import sys
from Tkinter import *
#modules
equation = '0'
def Entrybox():
theinput = inputbox.get()
if type(theinput) is float:
pass
elif type(theinput) is int:
equation += theinput
else:
return 'Numbers Only'
def bp1():
equation = equation + '1'
def bp2():
equation = equation + '2'
def bp3():
equation = equation + '3'
def bp4():
equation = equation + '4'
def bp5():
equation = equation + '5'
def bp6():
equation = equation + '6'
def bp7():
equation = equation + '7'
def bp8():
equation = equation + '8'
def bp9():
equation = equation + '9'
def bp0():
equation = equation + '0'
def bpplus():
equation = equation + '+'
def bpmin():
equation = equation + '-'
def bpmulti():
equation = equation + '*'
def bpdiv():
equation = equation + '/'
def bpequal():
eval(equation)
return
def bpclear():
equation = equation - equation
gui = Tk()
inputvar = StringVar()
#gui Size
gui.geometry('360x400')
#title
gui.title("A Lucas Calculator")
#The input box
inputbox = Entry(gui, textvariable = inputvar, bd = 10,width = 34)
inputbox.place(x = 40, y = 50)
#buttons
number3 = Button(gui, text = '3',font = 15,width = 4,command = bp3)
number3.place(x = 200,y = 260)
number2 = Button(gui, text = '2',font = 15,width = 4,command = bp2)
number2.place(x = 120,y = 260)
number1 = Button(gui, text = '1',font = 15,width = 4, command = bp1)
number1.place(x = 40,y = 260)
number6 = Button(gui, text = '6',font = 15,width = 4,command = bp6)
number6.place(x = 200,y = 200)
number5 = Button(gui, text = '5',font = 15,width = 4,command = bp5)
number5.place(x = 120 ,y = 200)
number4 = Button(gui, text = '4',font = 15,width = 4,command = bp4)
number4.place(x = 40, y = 200)
number9 = Button(gui, text = '9',font = 15,width = 4, command = bp9)
number9.place(x = 200,y = 140)
number8 = Button(gui, text = '8',font = 15,width = 4,command = bp8)
number8.place(x = 120,y = 140)
number7 = Button(gui, text = '7',font = 15,width = 4,command = bp7)
number7.place(x = 40,y = 140)
number0 = Button(gui, text = "0",font = 15,width = 4,command = bp0)
number0.place(x = 120,y = 318)
signplus = Button(gui, text = "+", font = 14, width = 3,bg = 'red', fg = 'white',command = bpplus)
signplus.place(x = 280,y = 140)
signmin = Button(gui, text = "-", font = 14, width = 3,command = bpmin)
signmin.place(x = 280,y = 200)
signmulti = Button(gui, text = "X", font = 14, width = 3,command = bpmulti)
signmulti.place(x = 280,y = 260)
signdiv = Button(gui, text = "/", font = 14, width = 3,command = bpdiv)
signdiv.place(x = 280,y = 318)
signequal = Button(gui, text = "=", font = 15, width = 4,bg = 'blue',fg = 'white',command = bpequal)
signequal.place(x = 200, y = 318)
clearbutton = Button(gui, text = "Clear", font = 14, width = 4,bg = "green", fg = "white",command = bpclear)
clearbutton.place(x= 40, y = 318)
gui.mainloop()

解决方案

由于您已连接一个textvariable到Entry,最容易做的事情就是使用它:

inputvar.set('numbers only')

Tkinter书中有关变量类的教程进行了更详细的解释……但实际上并没有太多要解释的内容。

(我假设您已在未显示给我们的代码中inputvar正确地创建了Tkinter.StringVar()该位置,并且您将其保留在某个位置,例如实例变量,以备后用。如果没有,显然您需要修复那些事。)

如果您没有使用textvariable,请参阅Entry文档,以获取有关其他方法的详细信息。

不幸的是,您编写的代码功能太破损而无法实现。

首先,Entrybox您定义的函数永远不会被调用,因此在该函数中执行的任何操作均可能不会产生任何效果。我不确定您希望在哪里调用它,因此无法为您解决该问题。

而且实际上没有地方可以进行这样的调用,因为所有事件处理函数在您单击它们后都会引发异常,因为它们都看起来像这样:

equation = equation + '1'

每当您在函数中分配变量时,这意味着它是局部变量,除非您另有明确说明。但你不必有一个名为局部变量equation,直到这个任务完成后,可是你要使用equation + '1'的值。因此,您将获得UnboundLocalError: local variable 'equation' referenced before assignment。

您真的不应该首先使用全局变量(GUI框架是类的范例用例之一,这就是为什么所有非平凡的Tkinter示例都以这种方式编写的原因,您应该遵循这些示例)。如果您确实想使用全局变量,则可以,但是您需要明确,例如:

def bp1():
global equation
equation = equation + '1'
同时,一旦弄清楚了在哪里以及如何打电话Entrybox,就会有很多问题:
def Entrybox():
theinput = inputbox.get()
if type(theinput) is float:
pass
elif type(theinput) is int:
equation += theinput
else:
return 'Numbers Only'

如果你有一个inputvar,你真的应该使用inputvar.get(),而不是直接去Entry。如所写,它不会引起任何问题,但是会使您的代码难以遵循。

更为严重的是,Entry.get总是返回一个字符串,*,这样theinput可以永远是一个int或浮动。因此,您的比较没有任何意义。即使它们确实有意义,也不是在Python中检查类型的方法-useisinstance(theinput, int),而不是type(theinput)。而且,如果您确实需要比较类型(这种情况很少见),则应该使用==而不是is。通常,如果您不知道想要哪一个,就想要==;仅is用于特定的惯用语(例如is None),或者当您要检查两个表达式是否命名完全相同的对象时,而不仅仅是它们具有相同的值。

无论如何,如果您要检查ininputvar中的字符串是否是可以转换为int的字符串,则可以这样做:

try:
value = int(theinput)
equation += theinput
except:
return 'Numbers Only'
And all of the same things apply for float, of course.
Once you fix all of those problems, and any others I didn't spot from a cursory glance, then you can change that return 'Numbers Only' to inputvar.set('Numbers Only'), and you're done.
However, there's a much, much better design for this whole thing. Just make each of the buttons insert a character onto the end of the Entry, and use the Entry's contents (which you can get from inputvar) as the equation, and use either Entry validation or StringVar tracing to handle illegal key entries. There's an example in that blog post, and another example in the official Entry docs linked above.
* Actually, it may be either kind of string—str or unicode—but let's ignore that.