13
A minimal Python Tkinter Parent-Children Data Form
I've made an example Python program that does nothing more than load two tables into a form and then lets you filter the "child" records by selecting rows in the "parent" table.
The idea here is to show a minimal-imports method of displaying parent-child records using the stock Tkinter and SQLite Python libraries.
In short: you can find the code at this online Git repository where there's really just the one Python file.
Here's how it looks:
It came about after I recently watched a YouTube video by Data Analytics Ireland. My many thanks to them for sharing that, but I wasn't pleased with the amount of code I had to wade through just to find the parts that made and loaded the records and then responded to which was clicked. I also felt a chance was missed to enact a parent-child behaviour between the two tables.
I first made my own rebuild as a way to test what I'd gleaned - using my usual stock interfacing (that's elsewhere in my GitLab presence). But then I decided it was unfair of me to moan about examples having unnecessary things in them - unless I tried doing that myself.
I'll let the README at the respository speak for itself, but will here discuss some of the vital parts. I won't cover the SQLite parts, so I'm assuming the simple SQL SELECT
statements are familiar - but do ask if you'd like those explained.
Here's the definition of the parent display control - using a Tkinter Treeview with added scoll bars and an action binding for when a row is selected.
# Parent records Treeview, scrollbars
tk_trvw_prnt = im_tkntr_ttk.Treeview( tk_frame_prnt_data)
tk_trvw_prnt.place( relheight=1.0, relwidth=1.0)
# adding scrollbars
tk_trvw_prnt_treescrolly = im_tkntr.Scrollbar(tk_frame_prnt_data, orient="vertical", command=tk_trvw_prnt.yview)
tk_trvw_prnt_treescrollx = im_tkntr.Scrollbar(tk_frame_prnt_data, orient="horizontal", command=tk_trvw_prnt.xview)
tk_trvw_prnt.configure( xscrollcommand=tk_trvw_prnt_treescrollx.set, yscrollcommand=tk_trvw_prnt_treescrolly.set)
tk_trvw_prnt_treescrollx.pack(side="bottom", fill="x")
tk_trvw_prnt_treescrolly.pack(side="right", fill="y")
tk_trvw_prnt.bind("<<TreeviewSelect>>", Cmd_trvw_prnt_on_tree_select)
Here's how the "parent" Treevew gets loaded, from two lists that were loaded via SQLite: a_rows
& a_names
for the data and column names.
a_didok, a_rows, a_names = SqLite_Filename_GetTable_Rows( ExampleDetail_Database_Filename(), ExampleDetail_Parent_Tablename() )
tk_trvw_prnt["column"] = a_names
tk_trvw_prnt["show"] = "headings"
for column in tk_trvw_prnt["columns"]:
tk_trvw_prnt.heading(column, text=column)
for row in a_rows:
tk_trvw_prnt.insert("", "end", values=row)
Of course, if we're reloading a table we'll need to clear the TreeView first, and that's done with the following (doing the "parent" again to go with the above):
for i in tk_trvw_prnt.get_children():
tk_trvw_prnt.delete(i)
Choosing to the reload the chld table is a matter of constructing a new SQL SELECT with a WHERE clause - but how do we get the value to use?
Here's how I wrote that step - into a separate function as I toyed with it, and done in small steps as I worked them out.
def GetCurrentParentKey():
slctn_prnt = tk_trvw_prnt.selection()
curItem = tk_trvw_prnt.focus()
curParts = tk_trvw_prnt.item( curItem)
curRow = curParts[ "values"]
clms_idx_pky = tk_trvw_prnt["column"].index(ExampleDetail_Parent_LinkColumnName())
pkyval = curRow[ clms_idx_pky ]
return pkyval
Doubtless, people with better Python skills than mine could reduce that to something much shorter and harder to follow.
p.s. I didn't want to post the whole code here, even though it will probably fit well enough in a Dev post - I just didn't want to be updating it in two places if I make changes.
13