2

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!

1
  • 1
    Try to do "binding" to treeview first (self.tree.bind("<Button-3>", self.click)). Right now there's only one bind to a frame, so it's unclear what you're expecting from that. Commented Oct 9, 2017 at 13:05

1 Answer 1

3

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)
Sign up to request clarification or add additional context in comments.

1 Comment

Thanks, I saw that I was binding incorrectly to the frame and when followed your advice, managed to resolve the issue and make it working! Moreover, the binding is much clearer to me now!

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.