Home > Mobile >  Call class Page1 from class Page2 Tkinter
Call class Page1 from class Page2 Tkinter

Time:03-06

I have found a post on stackoverflow (linked here), which has been very cool to test out, but I cannot for the life of me figure out how I would show page1, from page 2 for example. Normally this is done via MainView class, but I do not want this.

Here is the code:

#Thanks to Bryan Oakley
class Page(Frame):
    def __init__(self, *args, **kwargs):
        Frame.__init__(self, *args, **kwargs)
    def show(self):
        self.lift()

class Page1(Page):
   def __init__(self, *args, **kwargs):
       Page.__init__(self, *args, **kwargs)
       label = Label(self, text="This is page 1").pack(side="top", fill="both", expand=True)

class Page2(Page):
   def __init__(self, *args, **kwargs):
       Page.__init__(self, *args, **kwargs)
       label = Label(self, text="This is page 3").pack(side="top", fill="both", expand=True)
       showp1 = Page1.show(root)
       b1 = Button(self, text="Page 1",font='Helvetica 15 bold italic', command=showp1,bg='#444444',fg='white',padx=20)
       b1.pack()

class MainView(Frame):
    def __init__(self, *args, **kwargs):
        Frame.__init__(self, *args, **kwargs)
        
        p1 = Page1(self)
        p2 = Page2(self)

some things I have tried calling from Page2:

Page1.show(root)
Page1.show(self)
Page1.show(Mainview(Root))
Page1.show(Page())

I've tried plenty more stuff, but cannot figure it out, if anyone can help, and maybe give me a short explanation, would be amazing! Thank you, and have a great day!

CodePudding user response:

Page1 is class but you need to use instance - p1

And this need to assign instances with self

class MainView(Frame):
    def __init__(self, *args, **kwargs):
        Frame.__init__(self, *args, **kwargs)
        
        self.p1 = Page1(self)
        self.p2 = Page2(self)

And later in pages use

self.master.p1.show()

self.master.p2.show()

And if you don't want to do this via MainView then you would have to assign instances to global variables - but this method is not preferred.

# default value at start 
#p1 = None
#p2 = None

class MainView(Frame):
    def __init__(self, *args, **kwargs):
        Frame.__init__(self, *args, **kwargs)
     
        global p1
        global p2

        p1 = Page1(self)
        p2 = Page2(self)

and later you could use p1, p2

p1.show()

p2.show()

EDIT:

Minimal working example for first version:

I had to use self.master.p2 in separated function change() because I couldn't use it driectly in __init__ because when I create p1 then it tries to access self.master.p2 which doesn't exist yet - and this raise error. If I use it in function then it tries to access self.master.p2 when I press button - and self.master.p2 already exists.

import tkinter as tk


class Page(tk.Frame):
    
    def show(self):
        self.lift()


class Page1(Page):
    
    def __init__(self, *args, **kwargs):
        super().__init__(*args, **kwargs)
       
        label = tk.Label(self, text="This is page 1")
        label.pack(side="top", fill="both", expand=True)

        b1 = tk.Button(self, text="Show Page 2", command=self.change)
        b1.pack()

    def change(self):
        self.master.p2.show()
        
class Page2(Page):
    
    def __init__(self, *args, **kwargs):
        super().__init__(*args, **kwargs)
       
        label = tk.Label(self, text="This is page 2")
        label.pack(side="top", fill="both", expand=True)
 
        b1 = tk.Button(self, text="Show Page 1", command=self.change)
        b1.pack()

    def change(self):
        self.master.p1.show()


class MainView(tk.Frame):
    
    def __init__(self, *args, **kwargs):
        super().__init__(*args, **kwargs)
        
        self.p1 = Page1(self)
        self.p1.grid(row=0, column=0, sticky='news')
        
        self.p2 = Page2(self)
        self.p2.grid(row=0, column=0, sticky='news')

        self.p1.show()

# --- main ---

root = tk.Tk()

main = MainView(root)
main.pack()

root.mainloop()
```
  • Related