Elle Nolan
Elle Nolan

Reputation: 399

How to print Tkinter variables as part of a string?

In regular Python 3.4, if you want to print a variable in the middle of a string, you do something like this:

x = 31
print("The value of x is %s" % (x))

And it will print The value of x is 31.

In Tkinter, if you want to have a label read a certain variable, you simply define the label and if at any point the variable of the label changes, the label updates automatically if it's a Tkinter label. For example:

var = StringVar()
var.set("Label")
label = Label(main, text=var)

However, if I want part of a string to be a variable in Tkinter...

items = IntVar()
items.set(14)
b = Button(main, text="I have %s items" % (items.get()), command=additem)

def additem():
    items.set(items.get() + 1)

...The button doesn't update. When I press it, the printed value remains "I have 14 items" instead of changing to "I have 15 items" as it should.

How should I go about doing this?

Upvotes: 1

Views: 13075

Answers (1)

fhdrsdg
fhdrsdg

Reputation: 10532

When I press it, the printed value remains "I have 14 items" instead of changing to "I have 15 items" as it should.

No, it shouldn't. You defined the text of the button as a string with the number that items had at that time. Nowhere are you telling the text to update. The text and textvariable attributes do very different things, text sets the text which doesn't update, textvariable takes a StringVar or other Tkinter variable and keeps the text updated to the contents of this variable. So also please note that your first example is wrong, you have to use the textvariable attribute there to bind a StringVar's contents to a button, not text.

I think the best solution is to not use an IntVar, just update the text manually using configure:

root = Tk()

def additem():
    global items
    items += 1
    b.configure(text="I have %s items" % (items))

items = 14
b = Button(root, text="I have %s items" % (items), command=additem)
b.pack()

root.mainloop()

Another option would be to split up the label into three labels and put them together in a frame like:

root = Tk()

def additem():
    items.set(items.get() + 1)

f = Frame(root)

items = IntVar()
items.set(14)

l0 = Label(f, text="I have")
l1 = Label(f, textvariable=items)
l2 = Label(f, text="items")

b = Button(root, text="Add item", command=additem)

l0.pack(side=LEFT)
l1.pack(side=LEFT)
l2.pack(side=LEFT)

f.pack()
b.pack()

root.mainloop()

Upvotes: 2

Related Questions