Unable use tk.mainloop() in tkinter on ubuntu 16.04.2 Unable use tk.mainloop() in tkinter on ubuntu 16.04.2 tkinter tkinter

Unable use tk.mainloop() in tkinter on ubuntu 16.04.2


While it my not seem like it, The tkinter window is in fact there. It is simple to small to see because no widgets are inside of it to expand it. Once you began to add widgets to the window, it becomes visible.

For example, to make a window appear using the code in question,

import tkinter as tkclass MainApplication(tk.Frame):    def __init__(self, parent, *args, **kwargs):        super(MainApplication, self).__init__(parent, *args, **kwargs)if __name__ == '__main__':    root = tk.Tk()    MainApplication(root).pack(side="top", fill="both", expand=True)    root.mainloop() 

You could add a tk.Button() widget to force the window to expand:

import tkinter as tkclass MainApplication(tk.Frame):    def __init__(self, parent, *args, **kwargs):        super(MainApplication, self).__init__(parent, *args, **kwargs)        # create a button widget to force the window to expand to fit        # the button        self.btn = tk.Button(self, text='btn', bg='blue')        self.btn.pack(side='bottom')if __name__ == '__main__':    root = tk.Tk()    MainApplication(root).pack(side="top", fill="both", expand=True)    root.mainloop()

Which shows the following window:

enter image description here


Try to change the main portion of your program a little bit like this:

if __name__ == '__main__':    root = tk.Tk()    your_class_instance = MainApplication(root)    print(your_class_instance)    root.mainloop()

You will see on your Terminal something like this: .140449273960656

Now let us go back to your original code:

 if __name__ == '__main__':        root = tk.Tk()        your_class_instance = MainApplication(root).pack(side="top", fill="both", expand=True)        print(your_class_instance)        root.mainloop()

You will see None on your Terminal.

Why? That is because the layout managers of tkinter (pack(), place() and grid()) always return None and MainApplication class has no widgets.

In other words, you try to display nothing.

Note that pack(your_options_list) is useless in this line:

MainApplication(root).pack(side="top", fill="both", expand=True)

Not only it is useless but it prevents the application from further scalability because there is no way to use an instance of MainApplication class.

Maybe this is not necessary for your actual problem, but just as a side note, since you are using Python 3, you can use: super().__init__(parent, *args, **kwargs) instead of super(MainApplication, self).__init__(parent, *args, **kwargs)

Proving the provided explanation.

The explanation I provided for your problem (the above why?) states there are 2 facts that lead you to that situation. If one of them is satisfied, the problem disappears:

  1. Leaving pack() in place but ask MainApplication to draw at least one widget:

    import tkinter as tkclass MainApplication(tk.Frame):    def __init__(self, parent, *args, **kwargs):        super(MainApplication, self).__init__(parent, *args, **kwargs)        # I add these 2 following lines        self.parent = parent        self.initialize_gui()def initialize_gui(self):   # Ok, let us draw one useless button for a test   self.button_1 = tk.Button(self.parent, text="Do nothing")   self.button_1.pack()if __name__ == '__main__':    root = tk.Tk()    MainApplication(root).pack(side="top", fill="both", expand=True)    root.mainloop()

You will see the GUI:

enter image description here

  1. Let MainApplication class not drawing any widget but remove the pack():

    import tkinter as tkclass MainApplication(tk.Frame):    def __init__(self, parent, *args, **kwargs):        super(MainApplication, self).__init__(parent, *args, **kwargs)       if __name__ == '__main__':    root = tk.Tk()    MainApplication(root) # Remove pack(...)    root.mainloop()

You can see the GUI:

enter image description here