I am making a simple GUI for a patient's list with patient's name and date of visiting, using tkinter and treeview, I have an entry where user should type the name of the patient and the idea is if the name of the patient is located in the list, the row (or rows) which contain patient's name to be highlighted(selected). Or the other option can be in the listbox with all patients, to display only the entries with the patient's name we search for.
I have not used treeview before and could not find much data about its functions and examples, so I am struggling with the selection/highlight part, any ideas would be helpful at this point....
My code so far is:
import tkinter
from tkinter import ttk
class MainPage:
def __init__(self,master):
self.master = master
self.frame = tkinter.Frame(self.master)
self.master.columnconfigure(0, weight=1)
self.master.columnconfigure(1, weight=3)
self.master.columnconfigure(2, weight=1)
self.master.columnconfigure(3, weight=1)
self.master.columnconfigure(4, weight=1)
self.searchfield = tkinter.Frame(self.master)
self.searchfield.grid(row=1, column=0, columnspan=4)
self.search_var = tkinter.StringVar()
self.search_var.trace("w", lambda name, index, mode: self.selected)
self.entry = tkinter.Entry(self.searchfield,
textvariable=self.search_var, width=45)
self.entry.grid(row=0, column=0, padx=10, pady=3)
self.searchbtn = tkinter.Button(self.searchfield, text='Search',
command=self.selected)
self.searchbtn.grid(row=0, column=1)
self.treeFrame = tkinter.Listbox(self.searchfield, width=45, height=45)
self.treeFrame.grid(row=1, column=0, padx=10, pady=3)
self.tree = ttk.Treeview( self.treeFrame, columns=('Name', 'Date'))
self.tree.heading('#0', text='ID')
self.tree.heading('#1', text='Name')
self.tree.heading('#2', text='Date')
self.tree.column('#1', stretch=tkinter.YES)
self.tree.column('#2', stretch=tkinter.YES)
self.tree.column('#0', stretch=tkinter.YES)
self.tree.grid(row=4, columnspan=4, sticky='nsew')
self.treeview = self.tree
self.i = 1
self.patient_list = [{"Name": "Jane", "Date": "05.09.2017"},
{"Name": "David", "Date": "04.09.2017"},
{"Name": "Patrick", "Date": "03.09.2017"}]
for p in self.patient_list:
self.tree.insert('', 'end', text="ID_"+str(self.i), values=
(p["Name"], p["Date"]))
self.i = self.i + 1
self.search_item = self.entry.get()
for p in self.patient_list:
if p["Name"] == self.search_item:
self.selected(self.search_item)
def selected(self):
currentItem = self.tree.focus()
print(self.tree.item(currentItem)['values'])
root=tkinter.Tk()
d=MainPage(root)
root.mainloop()
Thanks in advance!
Some sort of search already implemented right from the box, so there's no need in another one!
All you need to do is supply proper tags to your patients. After that you can search by these tags (yeah, you can supply multiple of them to a specified patient) and control appearance/highlighting of patients (rows of treeview).
Let's play around:
Right now this just highlight a patient...
... but you can easily modify this with pair of
.detach()
and.move()
to sort entire treeview.Also, you can implement a partial search with few lines of code:
In conclusion, there's no need in reinventing the wheel, but if your treeview is mutable by user - keep in mind that these tags must be synched with mutable content.
More about treeview can be found here.
Please see my explained snippet below:
So with this, every time the
entry
widget is updated, we cycle through the list of names and check if the value of theentry
widget matches the value of theelement
in thenames
list
up to the length of the value of theentry
widget (EG, if we enter a five character long string then we check against the first five characters of the element).If they match then we append the
id
of the tree entry to alist
.After all the names have been checked we pass the
list
of matchingid
s intoself.tree.selection_set()
which then highlights all of the matching tree entries.