In tkinter, how can I insert the value of an inherited class variable into a Label widget?
The issue I am having is specifically with the Label widget. In the linked code, the tests for Text widgets and Button widgets both grab the inherited value and display it correctly.
You can find the Label widget in question in class PageTwo
The variable I am trying to inherit and display within the Label is the "num" variable set in the first class.
The goal is to take that variable, set the value in another class, and then display the newly set value later in a Label widget.
I have tried to set the Label to display the variable directly, as a str value, within an f-string, as well as setting a local variable within PageTwo to take the value of TestClass.num
Example of the code in question is:
import tkinter as tk
class TestClass(tk.Tk):
num = None
def __init__(self, *args, **kwargs):
tk.Tk.__init__(self, *args, **kwargs)
tk.Tk.wm_title(self, "Game")
container = tk.Frame(self)
container.pack(side="top", fill="both", expand=True)
container.grid_rowconfigure(0, weight=1)
container.grid_columnconfigure(0, weight=1)
self.frames = {}
for F in (PageOne, PageTwo):
frame = F(container, self)
self.frames[F] = frame
frame.grid(row=0, column=0, sticky="nsew")
self.show_frame(PageOne)
def show_frame(self, cont):
frame = self.frames[cont]
frame.tkraise()
class PageOne(tk.Frame):
def __init__(self, parent, controller):
tk.Frame.__init__(self, parent)
label = tk.Label(self,
text="Make a selection",
wraplength=450, justify='center')
label.pack(padx=10, pady=10)
TestClass.num = tk.StringVar()
tk.Radiobutton(self, text="1", variable=TestClass.num, value="1", ).pack()
tk.Radiobutton(self, text="2", variable=TestClass.num, value="2", ).pack()
tk.Radiobutton(self, text="3", variable=TestClass.num, value="3", ).pack()
view_selection = tk.Button(self, text="test selection", command=lambda: print(TestClass.num.get()))
view_selection.pack()
next_page = tk.Button(self, text="Next Page",
command=lambda: controller.show_frame(PageTwo))
next_page.pack(pady=10, padx=10)
class PageTwo(tk.Frame):
def __init__(self, parent, controller):
tk.Frame.__init__(self, parent)
# label = tk.Label(self, text=TestClass.num.get()
label = tk.Label(self, text=f"The number should show up here -> {TestClass.num.get()} <- ")
label.pack()
text1 = tk.Text(self)
text1.pack()
see_num = tk.Button(self, text="View Number",
command=lambda: text1.insert('1.0', TestClass.num.get()))
see_num.pack(pady=10, padx=10)
app = TestClass()
app.mainloop()
I have come across such uses of controller for a while now but never really got to know where the idea arose from. Anyway over here I see the problem might actually be in the program flow(when you instantiate with F(container, self)
you are executing the __init__
of that class, hence the values are already being set.
When you select each item in the radio button, you want the value of the label to appropriately edit itself. So for that I think static variables are more appropriate(to access the widgets inside another class) and you can use command
to fire a callback.
Also you need to fix the tristate issue of your Radiobutton
, by giving different initial value to the StringVar
to not be equal to the tristatevalue
of Radiobutton
or giving different tristatevalue
to each radiobutton or to use ttk.Radiobutton
that does not use this tristatevalue
.
So the changes to be made for PageTwo
are to create some static variables:
class PageTwo(tk.Frame):
label = ''
text = ''
def __init__(self, parent, controller):
tk.Frame.__init__(self, parent)
PageTwo.text = "The number should show up here -> {} <- " # {} so we can `format` it to be whatever text we want, later
PageTwo.label = tk.Label(self, text=self.text.format(''))
PageTwo.label.pack()
...
...
And in PageOne
, you need to set a command
for Radiobutton
that will be called each time an option is changed.
class PageOne(tk.Frame):
def __init__(self, parent, controller):
...
...
TestClass.num = tk.StringVar(value=' ')
command = lambda *args: PageTwo.label.config(text=PageTwo.text.format(TestClass.num.get()))
tk.Radiobutton(self, text="1", variable=TestClass.num, value="1",command=command).pack()
tk.Radiobutton(self, text="2", variable=TestClass.num, value="2",command=command).pack()
tk.Radiobutton(self, text="3", variable=TestClass.num, value="3",command=command).pack()
...
...
Another method I think possible is to create a function to create widgets, and load that up later when the page is supposed to be showed.