I am working on a "treeview" list of patient, in which we can search for a patient and select one. I would like to right-click on the selected patient and open a new page with info about the patient:
try:
import tkinter
from tkinter import ttk
except ImportError:
import Tkinter as 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=150)
self.treeFrame.grid(row=1, column=0, padx=10, pady=3)
self.tree = ttk.Treeview( self.treeFrame, columns=('Status', 'Name', 'Date'))
self.tree.heading('#0', text='Status')
self.tree.heading('#1', text='Name')
self.tree.heading('#2', text='Date')
self.tree.heading('#3', text='Transact Code')
self.tree.column('#0', stretch=tkinter.YES)
self.tree.column('#1', stretch=tkinter.YES)
self.tree.column('#2', stretch=tkinter.YES)
self.tree.column('#3', stretch=tkinter.YES)
self.tree.grid(row=0, columnspan=4, sticky='nsew')
self.treeview = self.tree
self.i = 1
self.patient_list = [{"Name":"Harry Thuku", "Date":"07.09.2017"},
{"Name":"stella stl", "Date": "07.09.2017"},
{"Name":"geg be", "Date": "07.09.2017"},
{"Name":"Henry Reeta", "Date": "06.09.2017"},
{"Name":"Henry Reeta", "Date": "06.09.2017"}]
for p in self.patient_list:
self.tree.insert('', 'end', text="ID_"+str(self.i), values=
(p["Name"], p["Date"]), tags=p["Name"])
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)
self.frame.bind("<Button-3>", self.click)
self.frame.grid_location(0, 0)
def selected(self):
search_for = self.search_var.get()
iid_to_select = ()
if search_for != '':
all_tags = self.master.tk.call(str(self.tree), "tag", "names")
tags_to_select = tuple(filter(lambda tag: search_for.lower() in tag.lower(), all_tags))
for sorted_tag in tags_to_select:
iid_to_select += self.tree.tag_has(sorted_tag)
self.tree.selection_set(iid_to_select)
def click(self, event):
print("Clicked at: ", event.x, event.y)
self.master.withdraw()
self.toplevel = tkinter.Toplevel(self.master)
self.toplevel.geometry("480x480")
app = PatientPage(self.toplevel)
class PatientPage:
#.....
pass
root = tkinter.Tk()
root.title("Login")
root.geometry("480x480")
Mainpage(root)
root.mainloop()
I am having trouble binding the right click of the mouse with the opening of the new window, I did some coding, but am not 100% understanding it hence it is not working...
Any thoughts on the subject would be helpful and appreciated!
First of all, bind the right click on the tree, not on the frame, i.e. replace self.frame.bind("<Button-3>", self.click)
by self.tree.bind("<Button-3>", self.click)
.
Then, you need to know on which item in the treeview the user has clicked. For that you can use self.tree.identify_row(event.y)
which returns the id of the item at position event.y
.
And, if you need to, you can retrieve the information on the patient stored in the treeview with self.tree.item(<item>, 'values')
.
So click
becomes:
def click(self, event):
item = self.tree.identify_row(event.y)
if item: # right click on a patient
self.master.withdraw()
self.toplevel = tkinter.Toplevel(self.master)
self.toplevel.geometry("480x480")
info = self.tree.item(item, 'values')
print(info)
app = PatientPage(self.toplevel)