Reputation: 11
from Tkinter import *
root = Tk()
armor = Label(root, text="Armor:", font=("Helvetica", 12))
armor.grid(row=1, column=0)
armorscale = Scale(root, from_=1337, to=20000, orient=HORIZONTAL, length=500)
armorscale.grid(row=1, column=1)
###
damage = Label(root, text="Base Damage:", font=("Helvetica", 12), justify=LEFT)
damage.grid(row=2, column=0)
damagescale = Scale(root, from_=100, to=2000, orient=HORIZONTAL, length=500)
damagescale.grid(row=2, column=1)
###
armorfloat = float(armorscale.get())
damagefloat = float(damagescale.get())
fReduction = float(armorfloat / (armorfloat + 12 * damagefloat))
sReduction = str(fReduction)
fTaken = damagefloat * (1 - (1* fReduction))
sTaken = str(fTaken)
###
def calc1():
armorfloat = float(armorscale.get())
damagefloat = float(damagescale.get())
fReduction = float(armorfloat / (armorfloat + 12 * damagefloat))
sReduction = str(fReduction)
fTaken = damagefloat * (1 - (1 * fReduction))
sTaken = str(fTaken)
print sReduction
print sTaken
return sReduction
return sTaken
###
reduction = Label(root, text="Reduction %:" + sReduction, font=("Helvetica", 12), justify=LEFT)
reduction.grid(row=3, column=0)
taken = Label(root, text="Damage Taken:" + sTaken, font=("Helvetica", 12), justify=LEFT)
taken.grid(row=4, column=0)
button = Button(root, text="Calculate", command=calc1)
button.grid(row=3, column=1, pady=5, sticky=E)
###
root.mainloop()
This is my first time trying to program anything so I'm a total noob. Everything seems to work fine and the print things are there just to prove it. Problem is that the values on the GUI are not updating at all after opening the program and moving the sliders or when clicking the calculate button.
Upvotes: 1
Views: 147
Reputation: 20679
You don't have to use a StringVar to change the text of a label (of course you can, but it is a very uncommon pattern in Tkinter programs). The text
option of a widget can be changed with the config
method or using the key "text"
, which is much easier:
label.config(text="new text")
# or
label["text"] = "new text"
So your labels' text can be updated without the need to use a StringVar for each label:
def calc1():
armorfloat = float(armorscale.get())
damagefloat = float(damagescale.get())
fReduction = float(armorfloat / (armorfloat + 12 * damagefloat))
fTaken = damagefloat * (1 - (1 * fReduction))
reduction.config(text="Reduction %:{}".format(fReduction))
taken.config(text="Damage Taken:{}".format(fTaken))
If you want to recalculate the values for the labels also when you move the sliders, use this function in the command
option of the Scale widgets:
Scale(..., command=lambda v: calc1())
Upvotes: 3
Reputation: 1860
As msw wrote: you can use a StringVar
but to update the labels inside your callback, you have to supply it the state
a common pattern, is to encapsulate the state inside a class, like in this answer: How to update image in tkinter label?
an alternative, is to pass it explicitly as an argument (here, using functools.partial for convenience)
(another alternative, is to directly modify the global module state, but I think it's not good practice: it's better to be explicit)
Also, removed useless float conversions, changed naming style to be a little bit more pep8 compliant, and removed the * import (though it should be better to explicitly access the Tkinter attributes now, since we're importing so many of them)
from Tkinter import Tk, Label, Scale, HORIZONTAL, LEFT, StringVar, Button, E
from functools import partial
root = Tk()
armorlabel = Label(root, text="Armor:", font=("Helvetica", 12))
armorlabel.grid(row=1, column=0)
armorscale = Scale(root, from_=1337, to=20000, orient=HORIZONTAL, length=500)
armorscale.grid(row=1, column=1)
###
damagelabel = Label(root, text="Base Damage:", font=("Helvetica", 12), justify=LEFT)
damagelabel.grid(row=2, column=0)
damagescale = Scale(root, from_=100, to=2000, orient=HORIZONTAL, length=500)
damagescale.grid(row=2, column=1)
###
damage_reduction = StringVar()
damage_taken = StringVar()
def calc1(reduction, taken):
armor = armorscale.get()
damage = damagescale.get()
reduction_value = armor / (armor + 12.0 * damage)
reduction.set("Reduction %%: %s" % reduction_value)
taken_value = damage * (1 - reduction_value)
taken.set("Damage Taken: %s" % taken_value)
###
reduction_label = Label(root, textvariable=damage_reduction, font=("Helvetica", 12), justify=LEFT)
reduction_label.grid(row=3, column=0)
taken_label = Label(root, textvariable=damage_taken, font=("Helvetica", 12), justify=LEFT)
taken_label.grid(row=4, column=0)
calc = partial(calc1, damage_reduction, damage_taken)
button = Button(root, text="Calculate", command=calc)
button.grid(row=3, column=1, pady=5, sticky=E)
calc()
###
root.mainloop()
Upvotes: 0