Reputation: 35
I have a problem with tkinter when a label refers to a value and I update the value by pressing a button. The value is indeed updated but the label text referring to this value is not.
How can I change this code that the button updates the value and the label refering to this value is updated and shown in the root
?
import tkinter
root = Tk()
root.title('Test Button')
root.geometry('600x450')
class Letter:
def __init__(self, value):
self.value = value
class Label:
def __init__(self, master):
self.a_label = tkinter.Label(root, text=current_letter.value)
self.a_label.grid(row=2, column=1)
class Button:
def __init__(self, master):
self.Button1 = tkinter.Button(master, height = 12, width = 24,
command= self.update_letter)
self.Button1.grid(row=1, column=1)
def update_letter(self):
current_letter.value
print("current_letter.value before: " + str(current_letter.value))
current_letter.value += 1
print("current_letter.value now: " + str(current_letter.value))
root.update
#initialize a
a = Letter(0)
current_letter = a
b = Button(root)
l = Label(root)
root.mainloop()
Upvotes: 1
Views: 1160
Reputation: 123413
My, what a big button you have.
If you use a tkinter Variable
, then updating it will automatically change what's in any widgets that refers to one of them. Here's some documentation describing them, and here's some more describing how to use them.
Here's how that could be done to the code in your question:
import tkinter
root = tkinter.Tk()
root.title('Test Button')
root.geometry('600x450')
class Letter:
def __init__(self, value):
self.value = tkinter.IntVar(value=value) # Store in a tkinter Variable.
class Label:
def __init__(self, master, letter):
self.a_label = tkinter.Label(master, textvariable=letter.value)
self.a_label.grid(row=2, column=1)
class Button:
def __init__(self, master, letter):
self.letter = letter
self.Button1 = tkinter.Button(master, height=12, width=24,
command=self.update_letter)
self.Button1.grid(row=1, column=1)
def update_letter(self):
current_value = self.letter.value.get()
print("letter.value before: " + str(current_value))
self.letter.value.set(self.letter.value.get() + 1)
print("letter.value now: " + str(self.letter.value.get()))
# initialize a
a = Letter(0)
b = Button(root, a)
l = Label(root, a)
root.mainloop()
A comment: I found having your own classes named the same as those in tkinter
a bit confusing because, while they superficially seem similar, they are actually very different—which could lead to difficult-to-understand programming errors.
Upvotes: 1
Reputation: 46669
It is because you did not update the label l
after you have updated current_letter
. The simple solution is to change current_letter
to IntVar
and update class Label
and Button
as below:
class MyLabel:
def __init__(self, master):
self.a_label = tkinter.Label(root, textvariable=current_letter)
self.a_label.grid(row=2, column=1)
class MyButton:
def __init__(self, master):
self.Button1 = tkinter.Button(master, height = 12, width = 24,
command= self.update_letter)
self.Button1.grid(row=1, column=1)
def update_letter(self):
value = current_letter.get()
print("current_letter.value before: ", value)
value += 1
print("current_letter.value now: ", value)
current_letter.set(value)
current_letter = tkinter.IntVar(0)
b = MyButton(root)
l = MyLabel(root)
Note that I have removed class Letter
as it is not necessary. I also rename class Label
and Button
to MyLabel
and MyButton
respectively as they are classes in tkinter.
Upvotes: 1
Reputation: 385
Welcome to Stackoverflow. First of all, you don't really need to create seperate classes for label and button in your program. You can create them inside of main class as tkinter
widgets. Then if you want to pass a variable of an instance of some class, you need to initiliaze it and pass to your update_letter
function properly, which you can use lambda
.
Here is an example code that you can work on:
import tkinter as tk
class UpdateLabel:
def __init__(self, master):
self.master = master
# Create instance of Letter class
a = Letter(value=0)
current_letter = a
self.update_button = tk.Button(master, text='Update', command=lambda:self.update_letter(current_letter))
self.update_button.grid(row=0, column=0)
self.label = tk.Label(master, text='No Value')
self.label.grid(row=1, column=0)
def update_letter(self, current_letter):
print("current_letter.value before: " + str(current_letter.value))
current_letter.value += 1
print("current_letter.value now: " + str(current_letter.value))
self.label.configure(text='Value: {}'.format(current_letter.value))
class Letter:
def __init__(self, value):
self.value = value
if __name__ == '__main__':
root = tk.Tk()
app = UpdateLabel(master=root)
root.mainloop()
In that link How to change label text, you can find other options for changing a text in tkinter label
widget.
I hope it helps
Upvotes: 1