如何在Tkinter上的Entry上显示文本



我正在尝试用GUI制作一个简单的计算器。到目前为止,我只有按钮和输入框设置,但我不知道如何在它们上显示文本。所以目前,"方程式"等于0。我想做的是,当用户按下相等按钮时,它会将求解的方程显示在名为inputbox的条目中。我必须做些什么才能将方程式显示回输入框?

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,请参阅条目文档以了解其他方法的详细信息。


不幸的是,您编写的代码函数太坏了,无法真正做到这一点。


首先,您定义的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或float。所以,你的比较毫无意义。即使它们确实有意义,这也不是在Python中检查类型的方法——使用isinstance(theinput, int),而不是type(theinput)。如果你真的需要比较类型(这是非常罕见的),你应该使用==,而不是is。一般来说,如果你不知道你想要哪一个,你就想要==;仅对特定的惯用情况(如is None)使用is,或者当您希望检查两个表达式是否命名完全相同的对象,而不仅仅是它们是否具有相同的值时。

无论如何,如果你想检查inputvar中的字符串是否是一个可以转换为int的字符串,方法是:

try:
value = int(theinput)
equation += theinput
except:
return 'Numbers Only'

当然,所有这些都适用于float


一旦你解决了所有这些问题,以及我粗略地看不到的任何其他问题,然后你可以将return 'Numbers Only'更改为inputvar.set('Numbers Only'),就完成了。


然而,这整件事有一个更好的设计。只需让每个按钮在条目的末尾插入一个字符,并使用条目的内容(可以从inputvar中获得)作为等式,然后使用条目验证或StringVar跟踪来处理非法密钥条目。这篇博客文章中有一个例子,上面链接的官方Entry文档中也有另一个例子。


*实际上,它可能是一种字符串——strunicode——但我们忽略它。

最新更新