7. Refreshing the table and selecting a row

Lines 113–127

These two functions keep the table and the form in sync. refresh clears the table and fills it again, and choose copies a clicked row into the form fields.

Code for this part

shop_manager.py, lines 113–127
113def refresh(query=''):114    for item in table.get_children():115        table.delete(item)116    for name, p in shop.products.items():117        if query in name.lower():118            table.insert('', 'end', values=(name, p['buy'], p['sell'], p['qty']))119 120def choose(event):121    selection = table.selection()122    if not selection:123        return124    name, buy, sell_price, qty = table.item(selection[0], 'values')125    for key, value in [('name', name), ('buy', buy), ('sell', sell_price), ('qty', qty)]:126        fields[key].delete(0, tk.END)127        fields[key].insert(0, value)

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 113def refresh(query=''):
refresh takes an optional parameter. If nothing is passed, query is the empty string and every product is shown. The function uses table, which is only created on line 137; that is fine, because a function body does not run until the function is called, and the first call is on line 145.
line 114for item in table.get_children():
get_children() returns the IDs of all rows currently in the table.
line 115table.delete(item)
Deletes each row from the table. This only removes the displayed row, not the product (unlike Shop.delete on line 44).
line 116for name, p in shop.products.items():
Loops over all products. items() yields (key, value) pairs: name is the product name and p its dictionary of prices and stock.
line 117if query in name.lower():
Shows only the products whose name contains the search text. The empty string is contained in every string, so '' in name is always True and everything is shown.
line 118table.insert('', 'end', values=(name, p['buy'], p['sell'], p['qty']))
Adds a row to the table. '' means a top-level row (not a child of another row), 'end' appends it at the bottom, and values gives the four columns in the order defined on line 136.
line 119
A blank line.
line 120def choose(event):
choose handles the row-selection event. tkinter passes an event object when it calls the function, so the event parameter is required even though it is not used. It is bound to the table on line 142.
line 121selection = table.selection()
selection() returns a tuple of the selected row IDs.
line 122if not selection:
If nothing is selected… This happens, for example, when refresh deletes the selected row and the event fires with an empty selection.
line 123return
…leave the function without doing anything.
line 124name, buy, sell_price, qty = table.item(selection[0], 'values')
Gets the values of the first selected row and unpacks them into four variables. The name sell_price (rather than sell) avoids confusion with the sell function (line 102). The values come back from the table as strings, for example '242400.0'.
line 125for key, value in [('name', name), ('buy', buy), ('sell', sell_price), ('qty', qty)]:
Loops over four (field key, value) pairs.
line 126fields[key].delete(0, tk.END)
Clears the entry box from index 0 to the end (tk.END).
line 127fields[key].insert(0, value)
Inserts the new value at the start of the box.

Note

After you click a row, the quantity box shows the product's stock. To record a sale you must change it to the number sold, otherwise the entire stock is sold.

How it connects to the rest of the code

See also

refresh(query='')
Called in run line 87, search line 107, by the “show all” button line 130 and for the initial fill line 145.
choose(event)
Bound to the table's <<TreeviewSelect>> event on line 142.
table
Created on line 137.
fields
Created on line 70 and filled on line 75.
shop.products
The data that changes on line 33, line 41, line 47 and line 58.

Check your understanding

Try to answer each question before opening it.

  1. Why does refresh() with no argument show every product?

    Show answer

    query is '', and the empty string is contained in every string, so line 117 is always true.

  2. Does table.delete(item) on line 115 remove a product from the shop?

    Show answer

    No. It only removes a row from the table; the data in shop.products is untouched.

  3. choose never uses event. Why is the parameter there?

    Show answer

    tkinter always passes an event object to a bound handler (line 142); without the parameter the call would fail with TypeError.

  4. What type are the values that table.item(...) returns on line 124?

    Show answer

    Strings, for example '242400.0'.