Intro — What We’re Doing

  • we’ll rephrase our import statement so we don’t have to keep typing the tkinter. prefix each time we make a library call, and
  • we’ll see how a tkinter Frame can pretend to be in a window and get away with it.

Here we go…

And Now, Some Neatly-phrased OOP

Results of This Example:

Current example output
Current example output
(click to enlarge)
Current example terminal output
Current example terminal output
(click to enlarge)


Changing the import statement so we’re left with the least amount of code to open a window looks something like this:

from tkinter import *

def main():
	window = Window()
	window.mainloop()

class Window(Tk):
	def __init__(self):
		super().__init__()

if __name__ == "__main__":
	main()

Breakdown

Yes, it’s another do-nothing example, but now we’re laying groundwork for what’s to come. Let’s look at the differences from our previous minimal example.

Import Everything and be Done with It

First, the tkinter. prefix:

tkinter.Tk()

This library call can be done like this now:

Tk()

Second, we derive our own Window class. It’s not necessary, but it helps keep our code neatly modular.

The Derived Window

At the top of the class, we define an __init__() method. For this demo, it isn’t important, but when we start passing arguments to the super-class, it will be. And that call is made with the super() prefix. Be careful with the order of the brackets, dot, and underscores. The call has to look like this:

super().__init__()

It’s awkward to type, but Pythonic as all git-out… OOPish, too.

There are other benefits to using a Window class which we’ll talk more about later.

main()

Instead of instantiating our window directly from the library, we instantiate the Window class. This keeps main() neat and tidy.

Note: For this and all future examples, we don’t have to change anything in main(). It’s evolved as far as it needs to.

The second line of main()—as before—opens the window.

Now let’s look at a pretentious frame…

It’s a Frame Up

Results of This Example:

Current example output
Current example output
(click to enlarge)
Current example terminal output
Current example terminal output
(click to enlarge)


So far, we’ve operated under the assumption that all tkinter applications need a window to put widgets in. Well, that’s not exactly true. We can get a window by sneaking in the back door, so to speak.

Here’s out next example:

from tkinter import *
from tkinter import ttk

def main():
	app = MainFrame()
	app.mainloop()

class MainFrame(ttk.Frame):
	def __init__(self, master = None):
		super().__init__(master)
		print(self.winfo_toplevel().winfo_children())
		
if __name__ == "__main__":
	main()

Breakdown

This code doesn’t include a statement to add a window, but a window still opens. I’m not saying this is a great idea, but it is possible.

We can see further proof of the window’s existence in the terminal where a list of the window’s children is displayed using a call to self.winfo_toplevel().winfo_children(). There’s only one child—the frame—but the point is made… a frame can be the highest-level widget defined in your code.

We’ll be coming back to winfo_toplevel() and more of its child methods in later posts because it’s a quick-n-easy way to access the attributes of an application’s window… including those we add for ourselves.

Conclusion

And that’s all for this time. Next time, we’ll see what a properly OOPed-up frame looks like as well as how it fits into the scheme of things.

‘Til then, take care of yourselves and may the elves of reusable code tinker with your tkinter.


Sponsorship


Comments? Questions? Observations?

Did we miss a tidbit of information that would make this post even more informative? Let's talk about it in the comments.

Thank you very much for dropping by!

© Copyright 2021 Ronald V. Tarrant