0

I have this frame that is displayed however, I want the last line to run only when this frame is actually shown (and not when the program runs). Things are happening in the function start which I only want happening when this frame is shown

class FrameTwo(reviseTen):
    def __init__(self, parent, controller):
        tk.Frame.__init__(self, parent)
        self.controller = controller
        self.instructions = tk.Label(self, text="Click on the option you think is correct, then click 'Proceed to next question'")
        self.startButton = tk.Button(self, text="Click here to start revision session")
        self.optionOne = tk.Button(self, text="Option One", command=super(FrameTwo, self).clickOptionOne)
        self.optionTwo = tk.Button(self, text="Option Two", command=super(FrameTwo, self).clickOptionTwo)
        self.optionThree = tk.Button(self, text="Option Three", command=super(FrameTwo, self).clickOptionThree)
        self.optionFour = tk.Button(self, text="Option Four", command=super(FrameTwo, self).clickOptionFour)
        self.question = tk.Label(self, text="What is the definition of: ")
        self.proceedButton = tk.Button(self, text="Proceed to next question", command=lambda: controller.show_frame(FrameThree))
############# EDIT ####################
        self.bind("<<Show>>", self.do_something)

def do_something(self, event):
    self.start()

EDIT Here is my show_frame method:

def show_frame(self, cont): # Method to show the current frame being used
    for frame in self.frames.values():
        frame.grid_remove()
    frame = self.frames[cont]
    frame.tkraise()
    frame.update()
    frame.grid()
    frame.event_generate("<<Show>>")
Jed Fox
  • 2,979
  • 5
  • 28
  • 38
YusufChowdhury
  • 309
  • 1
  • 3
  • 10
  • `class FrameTwo(reviseTen)` - what is `reviseTen`, and why is `FrameTwo` inheriting from it? Why do you call `tk.Frame.__init__` instead of `reviseTen.__init__` or `super().__init__`? – user2357112 Mar 29 '17 at 19:30
  • 2
    Please do not vandalize your posts. Once you've posted a question, it belongs to the Stack Overflow community at large (under the [CC-by-SA license](https://creativecommons.org/licenses/by-sa/3.0/)). If you would like to disassociate this post from your account, see [What is the proper route for a dissociation request?](https://meta.stackoverflow.com/q/323395/5244995). – Jed Fox May 14 '17 at 13:55

1 Answers1

3

The main problem is that you are using code you don't understand. You should probably start with a simpler architecture until you are able to understand how it works.

That being said, there are several simple solutions. For example, you can modify the show_frame method to either directly call a method in each page, or it can send an event which you can bind a function to.

For example:

class SampleApp(tk.Tk):
    ...
    def show_frame(self, page_name):
        '''Show a frame for the given page name'''
        frame = self.frames[page_name]
        frame.tkraise()
        frame.event_generate("<<Show>>")

class FrameTwo(reviseTen):
    def __init__(self, parent, controller):
        ...
        self.bind("<<Show>>", self.do_something)

    def do_something(self, event):
        self.start()

Note: since FrameTwo inherits from reviseTen, you shouldn't call Super(FrameTwo, self).start(), you can just call self.start().

Bryan Oakley
  • 370,779
  • 53
  • 539
  • 685
  • I apologize for the "self" error. I updated the answer. – Bryan Oakley Mar 30 '17 at 18:03
  • 1
    @yusufchowdhury: it sounds like you did the binding incorrectly, but I can't see your code so I can't say for sure. Make sure the binding is to `self.do_something` and not `self.do_something()` – Bryan Oakley Mar 30 '17 at 18:30
  • The code where I am binding is exactly like yours and other solutions I just saw, however, my show_frame is a little different and I am not able to tell if that is causing the issue - UPDATE - I used the code on this solution: http://stackoverflow.com/questions/36293437/tkinter-run-function-after-frame-is-displayed yet it still doesnt work – YusufChowdhury Mar 30 '17 at 18:37
  • I added my binding code, I can't seem to spot the error – YusufChowdhury Mar 30 '17 at 18:41
  • @yusufChowdhury: Since it is not possible for `do_something` to be called unless the event is generated, and the only way the event is generated is if you call `show_frame`, the logical conclusion is that you are calling `show_frame` on this window when the app starts. – Bryan Oakley Mar 30 '17 at 18:48
  • This is getting very long - I apologise, it IS working. I did not amend the code on my other frames so I thought it was not working. I am so sorry about this - and thank you again – YusufChowdhury Mar 30 '17 at 19:07
  • Hi there, I tried implementing your code to re-size my frames so it is only as large as it needs to be from: http://stackoverflow.com/questions/35991126/tkinter-frame-resize - however on the pages where I used bind to run a function, the page is empty (the function is used to populate and edit text for different widgets). Do I need to change the way I bind functions to make it compatible with the frame resizing? – YusufChowdhury Apr 06 '17 at 11:33