This question already has an answer here:
I am a beginner in python. I have a problem with using variable in different class. Please help. Here is the sample code from Using buttons in Tkinter to navigate to different pages of the application?
import Tkinter as tk
class Page(tk.Frame):
def __init__(self, *args, **kwargs):
tk.Frame.__init__(self, *args, **kwargs)
def show(self):
self.lift()
class Page1(Page):
def __init__(self, *args, **kwargs):
Page.__init__(self, *args, **kwargs)
label = tk.Label(self, text="This is page 1")
label.pack(side="top", fill="both", expand=True)
entry = tk.Entry(self)
entry.pack()
class Page2(Page):
def __init__(self, *args, **kwargs):
Page.__init__(self, *args, **kwargs)
label = tk.Label(self, text="This is page 2")
label.pack(side="top", fill="both", expand=True)
text = tk.Text(self, entry.get())
root.after(...)
class MainView(tk.Frame):
def __init__(self, *args, **kwargs):
tk.Frame.__init__(self, *args, **kwargs)
p1 = Page1(self)
p2 = Page2(self)
buttonframe = tk.Frame(self)
container = tk.Frame(self)
buttonframe.pack(side="top", fill="x", expand=False)
container.pack(side="top", fill="both", expand=True)
p1.place(in_=container, x=0, y=0, relwidth=1, relheight=1)
p2.place(in_=container, x=0, y=0, relwidth=1, relheight=1)
b1 = tk.Button(buttonframe, text="Page 1", command=p1.lift)
b2 = tk.Button(buttonframe, text="Page 2", command=p2.lift)
b1.pack(side="left")
b2.pack(side="left")
p1.show()
if __name__ == "__main__":
root = tk.Tk()
main = MainView(root)
main.pack(side="top", fill="both", expand=True)
root.wm_geometry("400x400")
root.mainloop()
Then it have two problems:
NameError: global name 'entry' is not defined
NameError: global name 'root' is not defined
How can i use these variable? Please help!
You're defining the variable
entry
inside the body of a method, this does not makeentry
accessible to the global scope, this is how you should embed objects:As you can see, you embed
label
andentry
objects toself
, the implied instance of classPage1
when you call classPage1()
. Any variable assigned inside a body of a method or a function becomes local to that method or function. That's how you should go with your code.Familiarize yourself with this concept: Short Description of Python Scoping Rules
Edit:
In class
Page2
If you really want to accessself.entry.get
of classPage1
, then you need to pass the object of class Page1 to the constructor of class Page2 and then fetch the entry from the object you passed toPage2.__init__
like the following:Here you must pass an object to the constructor and then you'll be able to access the object's attributes including its bound methods. The reason why I did this though is because in your
Page1
class you passedself
totk.Entry
so I thought you probably wanted to use the returned results ofself.entry = tk.Entry(self)
ofPage1
. If you don't really intend to use the returned results ofself.entry = tk.Entry(self)
ofPage1
class then you can add the same assignment in the constructor ofPage2
:self.entry = tk.Entry(self)
.