user3150197
user3150197

Reputation: 1

How to show text on Entry on Tkinter?

I am trying to make a simple calculator with 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. 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()

Upvotes: 0

Views: 5877

Answers (1)

abarnert
abarnert

Reputation: 365717

Since you've already attached a textvariable to the Entry, the easiest thing to do is to use it:

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.

(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.)


If you weren't using a textvariable, see the Entry docs for details on other ways to do it.


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. 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. So, you will get 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). 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:

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. 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. 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). And if you really need to compare types (which is very rare), you should use ==, not 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.

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:

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.

Upvotes: 1

Related Questions