Your first GUI program - Tkinter tutorial series 02

Posted by dynodins on Tue, 08 Mar 2022 21:17:47 +0100

preface

Jingdong coupon https://m.fenfaw.net/

Welcome to my personal blog Chens life
Tk series tutorials:

  • Tkinter tutorial series 01 - Introduction and installation Tk

We will write a foot and meter conversion program. Through this program, we will understand how to design and write a real utility program, and we will also understand the basic appearance of Tk program. You don't have to master all the knowledge in it. More details will be discussed in later chapters. This section only requires understanding, so that readers can understand how to design and write a Tk GUI program.

Design

We are going to write a simple GUI tool to convert feet into meters. According to our experience, it should look like the following (Figure 1):

This program will have an input box to input the number of feet, a display box to display the converted number, and several text areas to display prompt characters. Equally important, there must be a conversion trigger button.

It is not difficult to find that this program is roughly divided into three rows and three columns, which is very important. It is related to the later geometry management (used to control the size and position of components), which will be discussed in the following chapters.

code

from tkinter import *
from tkinter import ttk

def calculate(*args):
    try:
        value = float(feet.get())
        meters.set((0.3048 * value * 10000.0 + 0.5)/10000.0)
    except ValueError:
        pass

root = Tk()
root.title("Feet to Meters")
mainframe = ttk.Frame(root, padding="3 3 15 15")
mainframe.grid(column=0, row=0, sticky=(N, W, E, S))
mainframe.columnconfigure(0, weight=1)
mainframe.rowconfigure(0, weight=1)

feet = StringVar()
meters = StringVar()

feet_entry = ttk.Entry(mainframe, width=7, textvariable=feet)
feet_entry.grid(column=2, row=1, sticky=(W, E))

ttk.Label(mainframe, textvariable=meters).grid(column=2, row=2, sticky=(W, E))
ttk.Button(mainframe, text="transformation", command=calculate).grid(column=3, row=3, sticky=W)

ttk.Label(mainframe, text="foot").grid(column=3, row=1, sticky=W)
ttk.Label(mainframe, text="be equal to").grid(column=1, row=2, sticky=E)
ttk.Label(mainframe, text="rice").grid(column=3, row=2, sticky=W)

for child in mainframe.winfo_children(): child.grid_configure(padx=5, pady=5)

feet_entry.focus()
root.bind('<Return>', calculate)

root.mainloop()

It will eventually look like this (Figure 2):

Step by step explanation

To write Tk program, we must first introduce Tkinter module.

from tkinter import *
from tkinter import ttk

These two lines tell Python that our program needs these two modules. First of all, tkinter is the standard package of Tk. When it is loaded, it will also cause the Tk function library to be loaded in your system. Secondly, ttk is newly added in Tk 8.5 to provide access to the Tk theme widget set introduced in Tk 8.5. Its basic idea is to separate the code that realizes the behavior of widgets from the code that realizes its appearance as much as possible. We won't go into it here.

It is worth noting that we have imported all functions from tkinter module, so we can call all functions of tkinter directly without adding prefix. However, we only imported the ttk module, so we should add the ttk prefix when using the functions in the ttk module.

If you want to change the old code to the new code, you will find that tkinter's name has changed from uppercase to lowercase tkinter, which began with Python 3.0.

root = Tk()
root.title("Feet to Meters")
mainframe = ttk.Frame(root, padding="3 3 15 15")
mainframe.grid(column=0, row=0, sticky=(N, W, E, S))
mainframe.columnconfigure(0, weight=1)
mainframe.rowconfigure(0, weight=1)

The calculate function will be explained later. It is put in the front because many subsequent statements need to call it.

The root = Tk() statement builds a main window, also known as the root window. Use root Title ("title") gives the window a name. ttk.Frame(root, padding="3 3 15 15") establishes a frame, which is divided into three rows and three columns with 15 pixels. We put this framework into the root window. The difference is that all our components are put into this framework instead of the root window.

Generally speaking, we can put all widgets into the root window, but the background of the main window may not match the components we added. At this time, we add an intermediate Frame and put the components into this intermediate Frame to ensure that the content matches the background.

Column configuration and rowconfigure tell Tk that when the main window is resized, the Frame frame above it should also be changed to take up extra space.

feet = StringVar()
meters = StringVar()
feet_entry = ttk.Entry(mainframe, width=7, textvariable=feet)
feet_entry.grid(column=2, row=1, sticky=(W, E))

ttk.Label(mainframe, textvariable=meters).grid(column=2, row=2, sticky=(W, E))
ttk.Button(mainframe, text="transformation", command=calculate).grid(column=3, row=3, sticky=W)

The above statements create three components on the main frame: input box, output area (Label, used to place the conversion result) and conversion button.

For each Widget, we need to do two things:

  1. establish
  2. place

They are all classes in the ttk module. When creating, we specify the parameters passed in: the placed frame, size, characters in the button, etc. As for the meaning of textvariable, it refers to the variable associated with the value in the input box or output box, and the type of this variable is the object of StringVar.

We use grid for geometric management, which means where the component will be placed (which row and which column). sticky indicates the line up mode of the component in the grid cell assigned to it. E, W, S and N mean East, West, North and south, similar to the center, left and right in the text editor.

ttk.Label(mainframe, text="foot").grid(column=3, row=1, sticky=W)
ttk.Label(mainframe, text="be equal to").grid(column=1, row=2, sticky=E)
ttk.Label(mainframe, text="rice").grid(column=3, row=2, sticky=W)

The above three lines create three text labels with specified contents and put them in the specified position.

for child in mainframe.winfo_children(): 
    child.grid_configure(padx=5, pady=5)
feet_entry.focus()
root.bind('<Return>', calculate)

These four lines of code have done a beautiful finishing work for our graphics.

The first two lines of code traverse all the components placed in the mainframe and add some borders around them so that they don't all crowd together. Of course, you can traverse these components separately and set them one by one, but this is not a convenient practice.

The third line of code tells Tk to focus the cursor on the input box when the program is running, so that the user does not have to click on the input box again.

The fourth line of code tells Tk to call the calculate function when the user presses Return (Enter in Windows). This is the same as pressing the button to call the calculate function.

def calculate(*args):
    try:
        value = float(feet.get())
        meters.set((0.3048 * value * 10000.0 + 0.5)/10000.0)
    except ValueError:
        pass

Here we define a calculate function call, which will be called when you press the Return, Enter (Windows), or conversion button. It obtains the value entered by the user from the input box, then converts it to the value in meters, and then sets the value in the input box to the correct result.

Obviously, the calculate function changes the value display in their respective input and output boxes (labels) by obtaining the feet and setting the meters. When the user's input changes, the value of the corresponding feed will be modified to the corresponding input value; When the meters are modified, the value displayed in the corresponding output box (label) will also change. This is the definition of feet_ When entering (input box) and label (output box), you should also specify the reason for the value of textvariable, and its value should be an object of StringVar. For example:

feet = StringVar()
meters = StringVar()
feet_entry = ttk.Entry(mainframe, width=7, textvariable=feet)
ttk.Label(mainframe, textvariable=meters).grid(column=2, row=2, sticky=(W, E))
root.mainloop()

The last sentence tells Tk to enter the event loop, which is necessary to make some run.

Postscript

To be continued... Welcome to continue to pay attention.

In the next chapter, we will explain the geometry management in Tk, which is the key to reasonably organize and place various components. The grid used in this section is one of them. Of course, it is also a difficulty.