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:
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:
Leaving
pack()
in place but askMainApplication
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:
Let
MainApplication
class not drawing any widget but remove thepack()
: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: