Reputation: 63
I´m studying some python and tkinter, and tried a very simple sample app.
A tkinter GUI, a label that displays text, and 2 buttons bellow. These buttons where supposed to change the text in the label, as it is linked to a StringVar through textvariable param...
What should happen, simply: Press "A" button and "A" will be shown at the label Press "B" button and "B" will be shown at the label
But when I press button "A" the program gives me NameError: name 'display_frame' is not defined.
Cant figure out what´s happening. I´m accessing the object attribute...
obs: as button A is problematic, not tried configure the function for button B
import tkinter
class TkinterWindow(tkinter.Tk):
def __init__(self):
super().__init__()
self.rowconfigure(0, weight=1)
self.columnconfigure(0, weight=1)
self.configure(background='orange')
class DisplayFrame(tkinter.Frame):
def __init__(self, parent):
super().__init__(parent)
self.rowconfigure(0, weight=1)
self.columnconfigure(0, weight=1)
self.configure(background='cyan')
self.grid(row=0, column=0, pady=5, padx=5, sticky='nsew')
self.text = tkinter.StringVar()
self.text.set('Hello')
self.display = tkinter.Label(self, textvariable=self.text, font=15, bg="#bebebe", relief="groove", bd=5, height=5 )
self.display.grid(sticky='nsew')
class ButtonsFrame(tkinter.Frame):
def __init__(self, parent):
super().__init__(parent)
self.rowconfigure(0, weight=1)
self.columnconfigure(0, weight=1)
self.columnconfigure(1, weight=1)
self.configure(background='green')
self.grid(row=1, column=0, pady=5, padx=5, sticky='nsew')
self.button_A = tkinter.Button(self, text='A', command=self.write_A)
self.button_A.grid(row=0, column=0, padx=15, sticky='nsew')
self.button_B = tkinter.Button(self, text='B')
self.button_B.grid(row=0, column=1, padx=15, sticky='nsew')
def write_A(self):
display_frame.text.set('A')
def main():
window = TkinterWindow()
display_frame = DisplayFrame(window)
buttons_frame = ButtonsFrame(window)
window.mainloop()
main()
Upvotes: 0
Views: 1350
Reputation: 15226
The main issue you are having is the class attribute self.text
is not visible to the other classes. One way to fix this is to move that variable to the main tk class and then just reference it. This is the quickest fix to your code.
import tkinter
class TkinterWindow(tkinter.Tk):
def __init__(self):
super().__init__()
self.rowconfigure(0, weight=1)
self.columnconfigure(0, weight=1)
self.configure(background='orange')
self.text = tkinter.StringVar()
self.text.set('Hello')
class DisplayFrame(tkinter.Frame):
def __init__(self, parent):
super().__init__(parent)
self.rowconfigure(0, weight=1)
self.columnconfigure(0, weight=1)
self.configure(background='cyan')
self.grid(row=0, column=0, pady=5, padx=5, sticky='nsew')
self.display = tkinter.Label(self, textvariable=self.master.text, font=15, bg="#bebebe", relief="groove", bd=5, height=5 )
self.display.grid(sticky='nsew')
class ButtonsFrame(tkinter.Frame):
def __init__(self, parent):
super().__init__(parent)
self.rowconfigure(0, weight=1)
self.columnconfigure(0, weight=1)
self.columnconfigure(1, weight=1)
self.configure(background='green')
self.grid(row=1, column=0, pady=5, padx=5, sticky='nsew')
self.button_A = tkinter.Button(self, text='A', command=self.write_A)
self.button_A.grid(row=0, column=0, padx=15, sticky='nsew')
self.button_B = tkinter.Button(self, text='B')
self.button_B.grid(row=0, column=1, padx=15, sticky='nsew')
def write_A(self):
self.master.text.set('A')
def main():
window = TkinterWindow()
display_frame = DisplayFrame(window)
buttons_frame = ButtonsFrame(window)
window.mainloop()
main()
That said you have a few things in your code you should be mindful of. Over use of self.
when it is not needed and applying the geometry manage inside the frame class is a bad idea as well.
Personally I would have built this all in one class.
import tkinter as tk
class TkinterWindow(tk.Tk):
def __init__(self):
super().__init__()
self.rowconfigure(0, weight=1)
self.columnconfigure(0, weight=1)
self.configure(background='orange')
self.text = tk.StringVar()
self.text.set('Hello')
display_frame = tk.Frame(self, background='cyan')
ButtonsFrame = tk.Frame(self, background='green')
display_frame.rowconfigure(0, weight=1)
display_frame.columnconfigure(0, weight=1)
ButtonsFrame.rowconfigure(0, weight=1)
ButtonsFrame.columnconfigure(0, weight=1)
ButtonsFrame.columnconfigure(1, weight=1)
display_frame.grid(row=0, column=0, pady=5, padx=5, sticky='nsew')
ButtonsFrame.grid(row=1, column=0, pady=5, padx=5, sticky='nsew')
tk.Label(display_frame, textvariable=self.text, font=15,
bg="#bebebe", relief="groove", bd=5).grid(row=0, column=0, sticky='nsew')
tk.Button(ButtonsFrame, text='A',
command=lambda: self.update_text('A')).grid(row=0, column=0, padx=15, sticky='nsew')
tk.Button(ButtonsFrame, text='B',
command=lambda: self.update_text('B')).grid(row=0, column=1, padx=15, sticky='nsew')
def update_text(self, value):
self.text.set(value)
TkinterWindow().mainloop()
Upvotes: 1