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¶
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 113
def refresh(query=''):¶ refreshtakes an optional parameter. If nothing is passed,queryis the empty string and every product is shown. The function usestable, 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 114
for item in table.get_children():¶ get_children()returns the IDs of all rows currently in the table.- line 115
table.delete(item)¶ - Deletes each row from the table. This only removes the displayed row, not the product (unlike
Shop.deleteon line 44). - line 116
for name, p in shop.products.items():¶ - Loops over all products.
items()yields (key, value) pairs:nameis the product name andpits dictionary of prices and stock. - line 117
if query in name.lower():¶ - Shows only the products whose name contains the search text. The empty string is contained in every string, so
'' in nameis alwaysTrueand everything is shown. - line 118
table.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, andvaluesgives the four columns in the order defined on line 136. - line 120
def choose(event):¶ choosehandles the row-selection event. tkinter passes an event object when it calls the function, so theeventparameter is required even though it is not used. It is bound to the table on line 142.- line 122
if not selection:¶ - If nothing is selected… This happens, for example, when
refreshdeletes the selected row and the event fires with an empty selection. - line 124
name, 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 thansell) avoids confusion with thesellfunction (line 102). The values come back from the table as strings, for example'242400.0'.
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
runline 87,searchline 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.
Why does
refresh()with no argument show every product?Show answer
queryis'', and the empty string is contained in every string, so line 117 is always true.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.productsis untouched.choosenever usesevent. 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.What type are the values that
table.item(...)returns on line 124?Show answer
Strings, for example
'242400.0'.