1

I am trying to learn python, Tkinter and oop. Below is the code that I wrote after following tutorial on effbot.org

    from Tkinter import Tk, Frame, Label

class Nexus(object):
    """Top level object which represents entire app"""
    def __init__(self, main_window):
        self.nexus_frame = Frame(main_window)
        self.nexus_frame.pack()

        self.label = Label(main_window, text="Tkinter")
        self.label.pack()





def main():
    main_window = Tk()
    nexus_app = Nexus(main_window)
    main_window.wm_title("Hello World Window")
    width = main_window.winfo_screenwidth()
    height = main_window.winfo_screenheight()
    main_window.wm_minsize(width=width-100, height=height-100)
    main_window.mainloop()

if __name__ == "__main__":
    main()

Here a top level window is created first and it is passed as argument to Nexus class where I am adding a frame and a label to the frame. Then I am setting the size of top level window relative to current screen size back in the main function.

My question is why was the top level window create in main function? Could it not be created inside __init__ of Nexus class itself? What difference would it make if main_window was create inside __init__ of Nexus class and mainloop() was started therein?

1 Answer 1

3

Once Tk.mainloop is entered, no further code will be executed. Instead, the Tk event loop will take over (hence the name).

What that means is that if you, eg, did something like this:

def main():
    ...
    main_window.mainloop()
    print 'Hello world!'

then that print statement would never be executed (or, at least, not while the GUI is running).


So, with that in mind, why is there a problem with creating the root window and executing main loop within the constructor (the __init__ statement)? Well, two basic reasons:

  • It would mean that the constructor never returns, which is unexpected. If a programmer sees this:

    def main():
        Nexus()
        print 'Hello world!'
    

    then he or she will expect that print statement to be executed. As a rule, you don't expect creating an instance of a class to be the kind of thing which will cause an infinite loop (as the event loop is).

  • Related to that is the second reason: it would not be possible to create more than one instance of Nexus, because as soon as you create one, Tk.mainloop will take over. Again, that's unexpected: a class is a description of a type of object, and you would normally expect to be able to instantiate more than one object like that.

    At the moment, if you write:

    def main():
        ...
        Nexus(main_window)
        Nexus(main_window)
    

    then you'll get two copies of your Nexus window on the screen. That's expected, and sensible. The alternative would not be.


So what's the take-away message?

When you're dealing with GUI programs, entering the event loop is the last thing you want to do. Your setup might involve creating one object (as now), or it might involve creating many objects (eg, a complex GUI app might have two or three windows).

Because we want to be able to write similar code in both cases, the usual approach is to create the root window (the Tk object) once, and then pass it in as a reference to any classes that need to know about it.

Sign up to request clarification or add additional context in comments.

5 Comments

Thanks, you are right, with everything in init of Nexus class I cannot create a second object. With this approach, I can have multiple classes create a part of GUI in main window and all I have to do is pass around the object. Doing GUI I have realized I cannot think in oop way at all, what would be a good resource to understand python+Tkinter+oop?
@anukalp I think it basically just comes down to thinking about OOP in a different way. Your GUI objects (Frames, Labels, Buttons etc) are still objects, just special ones. If you look inside Tk, you'll see that a lot of the magic comes down to inheritance from Tk.Widget -- ie, OOP. Sadly I can't provide any really good resources as I don't use Tk much myself :(
While a little old, I've found Thinking in Tkinter a very useful free resource for grokking Tkinter. effbot is fantastic as a reference, but Thinking in Tkinter is more of a step-by-step walkthrough.
I'm also partial to these notes, and the next section, which are a bit more recent (disclaimer: written by a colleague of mine).
As far as current date, effbot is down. Here's a link to the site in Way Back Machine: web.archive.org/web/20200731175950/http://www.effbot.org

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.