A minimal Python Tkinter Parent-Children Data Form
Tags: python, sql, tkinter
Published: 2021-11-20 03:11:34

---
title: A minimal Python Tkinter Parent-Children Data Form
published: true
description: An example of a Parent-Children Data Form using minimal imports
tags: python,sql,tkinter
//cover_image: https://direct_url_to_image.jpg
---

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](https://gitlab.com/geraldew/example-dataform-parentchildren-minimal) where there's really just the one Python file.

Here's how it looks:

![Screenshot](https://gitlab.com/geraldew/example-dataform-parentchildren-minimal/-/raw/main/Screenshot.png)

It came about after I recently watched a [YouTube video](https://www.youtube.com/watch?v=GKk-PBZKl1o) 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.

```Python
	# 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.

```Python
		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):

```Python
		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.

```Python
	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.