5. The window and the input form

Lines 65–75

From here on the code leaves the class and builds the user interface. First the shop object and the main window are created, then a loop builds four rows of label and entry box: name, purchase price, sale price and quantity.

Code for this part

shop_manager.py, lines 65–75
65shop = Shop()66root = tk.Tk()67root.title('مدیریت فروشگاه - Python')68root.geometry('760x560')69 70fields = {}71for row, (key, label) in enumerate([('name', 'نام کالا'), ('buy', 'قیمت خرید'), ('sell', 'قیمت فروش'), ('qty', 'تعداد')]):72    ttk.Label(root, text=label).grid(row=row, column=0, padx=8, pady=5, sticky='e')73    entry = ttk.Entry(root, width=28)74    entry.grid(row=row, column=1, padx=8, pady=5)75    fields[key] = entry

Click a line number to jump to its explanation; click “line …” in an explanation to highlight that line in the code.

Line by line

line 65shop = Shop()
Creates a Shop object. This runs __init__ (line 9) and loads the data from disk. shop is a global variable used by every function further down the file.
line 66root = tk.Tk()
Creates the program's main window. A tkinter program has exactly one Tk(), and every other widget lives inside it.
line 67root.title('مدیریت فروشگاه - Python')
The text shown in the window's title bar.
line 68root.geometry('760x560')
The initial window size: 760 pixels wide by 560 high. The string format is 'WIDTHxHEIGHT'.
line 69
A blank line.
line 70fields = {}
An empty dictionary that will hold the entry boxes under the keys name, buy, sell and qty, so the name box can later be reached with fields['name'].
line 71for row, (key, label) in enumerate([('name', 'نام کالا'), ('buy', 'قیمت خرید'), ('sell', 'قیمت فروش'), ('qty', 'تعداد')]):
Loops over a list of four (key, label) tuples. enumerate numbers them 0 to 3 into row, and (key, label) unpacks each tuple. On the first pass row is 0, key is 'name' and label is the product-name label.
line 72ttk.Label(root, text=label).grid(row=row, column=0, padx=8, pady=5, sticky='e')
Creates a text label and immediately places it with grid at row row, column 0. padx and pady add space around it, and sticky='e' pins it to the east (right) side of its cell. The label is never needed again, so it is not stored.
line 73entry = ttk.Entry(root, width=28)
Creates an entry box 28 characters wide and keeps it in entry.
line 74entry.grid(row=row, column=1, padx=8, pady=5)
Places the box in column 1 of the same row. This is done on its own line on purpose, because grid returns None: writing entry = ttk.Entry(...).grid(...) would leave entry set to None, and its text could never be read.
line 75fields[key] = entry
Stores the box in fields under its key.

Note

Rows 0 to 3 of the window grid hold this form. Row 4 holds the buttons (line 132) and row 5 the table (line 141).

How it connects to the rest of the code

See also

shop
Used in add line 94, edit line 97, delete line 100, sell line 103, report line 110 and refresh line 116.
root
Parent of every widget: labels line 72, entry boxes line 73, the button frame line 131, the table line 137. Resizing is set up on line 143 and line 144, and the main loop starts on line 146.
fields
Read in values line 78–line 81, delete line 100, sell line 103 and search line 106; written in choose line 126 and line 127.

Check your understanding

Try to answer each question before opening it.

  1. Why are line 73 and line 74 two lines instead of entry = ttk.Entry(...).grid(...)?

    Show answer

    grid returns None, so entry would be None and its text could never be read.

  2. Which values does row take in the loop on line 71?

    Show answer

    0, 1, 2 and 3 — one per form field, from enumerate.

  3. What does sticky='e' do on line 72?

    Show answer

    It pins the label to the east (right) side of its grid cell.

  4. When does Shop.__init__ run?

    Show answer

    Once, on line 65, when shop = Shop() creates the object.