1

I have the following code that allow me to change page without problems (more than other overlap the frames):

class HFlair(tk.Tk):

    def __init__(self, *args, **kwargs):
        tk.Tk.__init__(self, *args, **kwargs)
        container = tk.Frame(self)
        container.pack(side="top", fill="both", expand=True)
        container.grid_rowconfigure(10, weight=1)
        container.grid_columnconfigure(10, weight=1)

        self.frames = {}
        for F in (StartPage, PageOne, PageTwo, PageThree):
            page_name = F.__name__
            frame = F(parent=container, controller=self)
            self.frames[page_name] = frame
            frame.grid(row=0, column=0, sticky="nsew")
        self.show_frame("StartPage")

    def show_frame(self, page_name):
        '''Show a frame for the given page name'''
        frame = self.frames[page_name]
        frame.tkraise()

class StartPage(tk.Frame):
    def __init__(self, parent, controller):
        tk.Frame.__init__(self, parent)
        self.controller = controller
        self.title=tk.Frame(self)
        self.title.pack(side="top")
        self.menu=tk.Frame(self)
        self.menu.pack(side="top")
        self.sub_title=tk.Frame(self)
        self.sub_title.pack(side="top")
        self.app1=tk.Frame(self)
        self.app1.pack(side="left")

        label = tk.Label(self.title, text="HFlair Home", font=TITLE_FONT)
        label.pack(side="top", fill="x", pady=10)
        button1 = tk.Button(self.menu, text="Membri",command=lambda: self.controller.show_frame("PageOne"))
        button2 = tk.Button(self.menu, text="Spese",command=lambda: self.controller.show_frame("PageTwo"))
        button3 = tk.Button(self.menu, text="Nuovo Membro",command=lambda: self.controller.show_frame("PageThree"))
        button1.pack(side="left")
        button2.pack(side="left")
        button3.pack(side="left")
        label1 = tk.Label(self.sub_title, text="Membri che non hanno pagato l'iscrizione:", font=text_font)
        label1.pack(side="top", fill="x", pady=10)
        c=table(self.app1,self.controller,'home')

I have more pages similar to the first one, I just didn't copy the code because almost identical.

If you can see I have different button that on click I change pages:

tk.Button(self.menu, text="Spese",command=lambda: self.controller.show_frame("PageTwo"))

Now my problem is that I have a functionality that return me an integer and I need call a new page passing this value. I try to call the page in the same way that I use to call all the other but I can't get it work with the extra value (an integer):

self.controller.show_frame("PageTwo",4) 

The problem is that every time that I had a new parameter as optional to the class for the new page my code fail in the class Hflair.

I try to pass the extra parameter as optional in the main class (class Hflair) but my code still failing.

Someone can help me please or explain how can I introduce an extra parameter just for 1 pages?

When I add the new parameter just to my page call I receive this error on this line:

frame = F(parent=container, controller=self)

init() missing 1 required positional argument: 'attr'

If I add an optional parameter in this way:

frame = F(parent=container, controller=self, attr=None)

I receive this error:

init() got an unexpected keyword argument 'attr'

I think that I'm making some stupid mistake but I don't get where :S

Sorry but I'm new of Tkinter.

Thanks so so much in advance for the help

Carlo 1585
  • 1,455
  • 1
  • 22
  • 40
  • What do you expect to happen when you pass a value to `show_page`? Are you aware that the other page will have already been created? How do you expect it to use this value? – Bryan Oakley Jan 17 '17 at 17:40
  • Have you read all of the other questions about switching frames to see if they help? Start here: http://stackoverflow.com/a/7557028/7432 – Bryan Oakley Jan 17 '17 at 17:42
  • Hi @BryanOakley so I know that the page was create but is created black. I make an example of what I want do, I have different users in the DB, I pass the page and the user id and dynamically take all the information from the DB, so I have one unique page with frames that overlap when I call a user profile! Am I doing wrong? – Carlo 1585 Jan 17 '17 at 18:28

1 Answers1

3

If you call function with extra argument

self.controller.show_frame("PageTwo",4) 

then you have to define function/method with extra argument

def show_frame(self, page_name, arg):

or more universal with default value so you can call show_frame() with or without extra argument

def show_frame(self, page_name, arg=None):

And then in show_frame() you have to do something with this argument

ie.

def show_frame(self, page_name, arg=None):
    '''Show a frame for the given page name'''
    frame = self.frames[page_name]
    frame.tkraise()

    if arg:
        frame.arg = arg
        # or
        frame.some_function(arg)

If you want to use argument when you create frame

frame = F(parent=container, controller=self, attr=some_value)

then you have to define all pages with extra argument

class StartPage(tk.Frame):
     def __init__(self, parent, controller, attr=None):

class PageOne(tk.Frame):
     def __init__(self, parent, controller, attr=None):

class PageTwo(tk.Frame):
     def __init__(self, parent, controller, attr=None):

but you have to use extra arguments in for loop

ie.

for F, arg in ((StartPage, 4), (PageOne, 1), (PageTwo, None), (PageThree, None)):
        page_name = F.__name__
        frame = F(parent=container, controller=self, attr=arg)

or use similar to show_frame

for F, arg in ((StartPage, 4), (PageOne, 1), (PageTwo, None), (PageThree, None)):
    page_name = F.__name__
    frame = F(parent=container, controller=self)

    if arg:
        frame.arg = arg
        # or
        frame.some_function(arg)

and then you don't need argument in F(...) and in __init__(...)

furas
  • 134,197
  • 12
  • 106
  • 148