Reputation: 275
So here's my code:
import tkinter as tk
class Window(tk.Tk):
def __init__(self, *args, **kwargs):
tk.Tk.__init__(self, *args, **kwargs)
self.container = tk.Frame(self)
self.container.pack(side="top", fill="both", expand = True)
self.label1 = tk.Label(self.container, text="label")
self.label1.pack()
self.fwd_button = tk.Button(self, text="Continue", command=lambda: books_display(subframe.Main_Title))
self.fwd_button.pack()
def print_label(self):
print (self.label1['text'])
class subframe_newscripts():
def __init__(self, parent):
self = tk.Frame(parent)
self.pack()
self.Main_Title = tk.Label(self, text="New Scripts")
self.Main_Title.grid(row=0, column=0)
self.Book_display_frame = tk.Frame(self)
self.Book_display_frame.grid(row=1, column=0)
def books_display(widget):
print (widget['text'])
app = Window()
subframe = subframe_newscripts(app)
app.mainloop()
I am trying to print the label "Main_title" with a button. When I run the program I get this error:
AttributeError: 'subframe_newscripts' object has no attribute 'Main_Title'
Not sure what I am doing wrong...
Upvotes: 0
Views: 40
Reputation: 15226
Your problem is due to this line:
self = tk.Frame(parent)
self
is used to reference the class and this is how we are able to access methods and class attributes from other methods and outside of the class. However you are actually redefining what self is to be a Frame and Frame's do not have the class attribute Main_Title
.
To correct this you want to define the Frame as a class attribute as well. Something like this will work fine:
self.frame = tk.Frame(parent)
All that said I would change a few things.
I would write the 2nd class to inherit from frame. I find it to be a bit cleaner and easier to maintain.
You should try to follow a standard naming convention. Your naming is not consistent. You should take some time to read PEP8 so your code is easier to read.
I prefer the use of super().__init__()
over tk.Tk.__init__()
as it works for most situations as well as the current standard for Python 3.
It prefer to apply the geometry manager outside of the class when your class is a container like a Frame. This way if you need to use that same frame elsewhere you can use any geometry manager without running into conflicts if you use grid()
or pack()
in different areas of your code.
Corrected and cleaned up code to follow PEP8 standards more closely:
import tkinter as tk
class Window(tk.Tk):
def __init__(self):
super().__init__()
container = tk.Frame(self)
container.pack(side="top", fill="both", expand = True)
self.label1 = tk.Label(container, text="label")
self.label1.pack()
tk.Button(self, text="Continue", command=lambda: books_display(sub_frame.main_title)).pack()
def print_label(self):
print(self.label1['text'])
class SubFrameNewScripts(tk.Frame):
def __init__(self, master):
super().__init__(master)
self.main_title = tk.Label(self, text="New Scripts")
self.main_title.grid(row=0, column=0)
self.book_display_frame = tk.Frame(self)
self.book_display_frame.grid(row=1, column=0)
def books_display(widget):
print(widget['text'])
if __name__ == '__main__':
app = Window()
sub_frame = SubFrameNewScripts(app)
sub_frame.pack()
app.mainloop()
Results:
Upvotes: 1