Before We Begin…

To run these demos:

  • type the code into an editor (I use Notepad++), or
  • download the script using the link below each screen-shot,
  • open a terminal (or Terminal, Command Prompt, Bash shell, or PowerShell — from now on, I’ll just say ‘terminal’),
  • navigate to where you saved the script, and
  • run it like so:
    • py <script>.py
  • or so:
    • python <script>.py
  • or so:
    • python3 <script>.py

Substitute the script name where it says <script>, naturally.

I’ll always indicate substitutions with angle brackets. It’s archaic, but clear.

Nit: Above, I said you can download the files, but repetitive typing of code examples is the best way to absorb this stuff.

Intro — What We’re Doing

We’ll be looking at:

  • a script version of the test we ran last time,
  • a simple OOP demo on which we can base an application, and
  • how to run the OOP demo from a separate script.

The Simplest tkinter Application

Results of This Example:

Current example output
Current example output
(click to enlarge)


As they say on TV, this is just a test. But it’s only two lines and—considering what it does—it’s pretty impressive. Here it is:

import tkinter
tkinter._test()

You’ll recognize the results from the quick test we did in Post #002 — Python and Font Installation. The difference is, this is how we get there using a script file.

Breakdown

There isn’t much to breakdown, but there are two tidbits of information to take away from this:

  • to use tkinter in a Python script, we have to import it, and
  • it’s now obvious that py -m on the command line is the same as an import statement in a script. The difference is that, on the command line, importing tkinter like this automatically runs the test. In our script, we have to call it explicitly.

A Minimal Window Demo

Results of This Example:

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


It’s possible to write a three-line script that opens a window, but it’s rather unPythonic, so let’s go with something a little more elaborate. Other than the quick test demo above, this is just about the least amount of code we can write to get an actual tkinter application while maintaining good coding practices. I did add one extra line (the print() statement) which we’ll discuss. Here’s the code:

import tkinter

def main():
	print(f"__name__: = {__name__}")
	window = tkinter.Tk()
	window.mainloop()
	
if __name__ == "__main__":
	main()

Breakdown

Again, we start by importing the tkinter library.

Skipping over that print() statement, the rest of main() declares and opens a window. I’ll get back to the print() statement in a second.

The window declaration does obscure what’s going on, so here’s the dope…

  • Tk() is the window class which is part of the tkinter module,
  • tkinter.Tk() is shorthand for calling tkinter.Tk().__init__() and that creates the window object, and
  • the window then opens when we call window.mainloop().

One other thing to note here. The way we imported tkinter means that every time we make a call to the tkinter library, we’ll have to prefix the call with tkinter. (the name of the library followed by a dot) to avoid a name <widget> not defined error. In the next demo—and from then on—we’ll change the way we import the library to avoid this situation.

That print() Statement

Let’s talk about in conjunction with the if statement at the bottom of the script…

Those few lines in the if statement check the script’s namespace. Python always gives an executing script the namespace __main__. As long as these lines appear at the end of an executed Python script, the if statement will always be True and main() will execute.

Now, let’s look back at the main() function were the print() statement writes the namespace to the terminal. Take a look at the terminal’s screen-shot above to see the results.

This only tells part of the namespace story, thought. To see exactly how namespaces work, we have to look at what happens when Python imports this script as a module…

Importing The Previous Demo

Results of This Example:

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


The next script looks like this:

import window_001_minimal

def main():
	window_001_minimal.main()

if __name__ == "__main__":
	main()

The import statement loads our previous script (note the absence of the .py suffix). It doesn’t mention the tkinter module because that’s imported in the script we’re importing here… window_001_minimal.py.

Also, main() doesn’t declare and open a window. For that, we reach into window_001_minimal.py and call that main() function instead. Let’s save this script as window_002_start_external.py.

Running this demo, we find that the namespace printed to the terminal is different. It’s now the same as the imported script’s file name… minus the .py extension. Compare this demo’s terminal screen-shot to the previous one to see how they differ.

But notice this… we’re testing for the namespace in exactly the same way in both scripts.

Script Namespace Awareness

Adding those two lines at the end of every script is a good habit to get into. Python takes care of namespace details so we don’t have to.

Conclusion

Next time, we’ll look at the Frame widget and peek into one of the back doors available when building GUI’s with tkinter. Until then, keep your campfires burning and, as they say in some parts, don’t let the COVID get you.


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