简体   繁体   English

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

[英]How to show text on Entry on Tkinter?

I am trying to make a simple calculator with GUI. 我正在尝试使用GUI创建一个简单的计算器。 So what I have so far are the buttons and the Entry box setup but I have no idea how to display text on them. 所以到目前为止,我只有按钮和输入框设置,但是我不知道如何在它们上显示文本。 So Currently, the "equation" is equal to 0. What I want to do is when the user presses the equal button, it would display the solved equation to the Entry called inputbox. 因此,当前,“等式”等于0。我要做的是当用户按下等号按钮时,它将在输入框(称为输入框)上显示已求解的方程式。 What will I have to do to display the equation back to the 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()

Since you've already attached a textvariable to the Entry , the easiest thing to do is to use it: 由于您已经将textvariable附加到Entry ,所以最简单的方法是使用它:

inputvar.set('numbers only')

The tutorial on The Variable Classes in the Tkinter book explains in more detail… but there's really not much more to explain. Tkinter书中有关变量类的教程进行了更详细的解释……但是实际上并没有太多解释。

(I'm assuming inputvar was properly created as a Tkinter.StringVar() somewhere in the code you haven't shown us, and that you're keeping it around somewhere, like an instance variable, for later use. If not, obviously you'd need to fix those things.) (我假设inputvar被正确的创建Tkinter.StringVar()在你还没有表现出我们的代码的地方,那你保持它周围的地方,像一个实例变量,以备后用。如果没有,很明显您需要修复这些问题。)


If you weren't using a textvariable , see the Entry docs for details on other ways to do it. 如果您没有使用textvariable ,请参阅Entry文档,以获取其他实现方法的详细信息。


Unfortunately, your code function as written is too broken to actually get this far. 不幸的是,您编写的代码功能太破损而无法实现。


First, the Entrybox function that you defined never gets called, so nothing you do in that function can possibly have any effect. 首先,您定义的Entrybox函数永远不会被调用,因此在该函数中执行的任何操作均可能不会产生任何效果。 I'm not sure where you wanted it to get called, so I can't fix that for you. 我不确定您希望在哪里调用它,因此无法为您解决该问题。


And there's nowhere you can actually put such a call, because all of your event handler functions will raise an exception as soon as you click them, because they all look like this: 而且实际上没有地方可以进行这样的调用,因为所有事件处理函数在您单击它们后都会引发异常,因为它们都看起来像这样:

equation = equation + '1'

Whenever you assign to a variable in a function, that means it's a local variable, unless you explicitly say otherwise. 每当您在函数中分配变量时,这意味着它是局部变量,除非您另外明确地声明。 But you don't have a local variable named equation until after this assignment finishes—and yet you're trying to use equation + '1' as the value. 但是,直到分配完成后,您才有了一个名为equation的局部变量,而您正在尝试使用equation + '1'作为值。 So, you will get UnboundLocalError: local variable 'equation' referenced before assignment . 因此,您将获得UnboundLocalError: local variable 'equation' referenced before assignment

You really shouldn't be using global variables in the first place (a GUI frame is one of the paradigm use cases for a class, which is why all of the non-trivial Tkinter examples are written that way, and you should follow those examples). 您真的不应该一开始就使用全局变量(GUI框架是类的范例用例之一,这就是为什么所有非平凡的Tkinter示例都以这种方式编写的原因,您应该遵循这些示例)。 If you really want to use globals, you can, but then you need to be explicit, like this: 如果您确实想使用全局变量,则可以,但是您需要明确,例如:

def bp1():
    global equation
    equation = equation + '1'

Meanwhile, once you figure out where and how to call Entrybox , there are a number of problems with it: 同时,一旦弄清楚了在何处以及如何调用Entrybox ,就会有很多问题:

def Entrybox():
    theinput = inputbox.get()
    if type(theinput) is float:
        pass

    elif type(theinput) is int:
        equation += theinput

    else:
        return 'Numbers Only'

If you've got an inputvar , you really should be using inputvar.get() , not going straight to the Entry . 如果您有一个inputvar ,那么您确实应该使用inputvar.get() ,而不要直接Entry As written, it won't cause any problems , but it makes your code harder to follow. 如所写,它不会引起任何问题 ,但会使您的代码难以遵循。

More seriously, Entry.get always returns a string,* so that theinput can never be an int or a float. 更严重的是, Entry.get总是返回一个字符串*,因此theinput 永远不能是int或float。 So, your comparisons make no sense. 因此,您的比较没有任何意义。 And even if they did make sense, that's not the way to check types in Python—use isinstance(theinput, int) , not type(theinput) . 即使它们确实有意义,也不是在Python中检查类型的方法-使用isinstance(theinput, int) ,而不是type(theinput) And if you really need to compare types (which is very rare), you should use == , not is . 如果确实需要比较类型(这种情况很少见),则应使用== ,而不是is In general, if you don't know which one you want, you want == ; 通常,如果您不知道想要哪一个,就需要== ; only use is for specific idiomatic cases (like is None ), or when you want to check that two expressions name the exact same object, not just that they have the same value. 只有使用is针对特定习惯的情况下(如is None ),或者当您要检查两个表达式名字完全相同的对象,而不仅仅是它们具有相同的价值。

Anyway, if you want to check whether the string in inputvar is a string that could be converted to an int, the way to do that is: 无论如何,如果您要检查inputvar中的字符串是否是可以转换为int的字符串,则可以这样做:

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

And all of the same things apply for float , of course. 当然,所有相同的事情也适用于float


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. 一旦解决了所有这些问题,以及所有我没发现的问题, 那么您就可以将return 'Numbers Only'值更改为inputvar.set('Numbers Only') ,然后就可以完成。


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. 只需使每个按钮在Entry的末尾插入一个字符,然后将Entry的内容(可以从inputvar获取)用作方程式,然后使用Entry验证或StringVar跟踪来处理非法的密钥条目。 There's an example in that blog post, and another example in the official Entry docs linked above. 该博客文章中有一个示例,上面链接的官方Entry docs中有一个示例。


* Actually, it may be either kind of string— str or unicode —but let's ignore that. *实际上,它既可以是字符串,也可以是strunicode但是我们可以忽略它。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM