5

I would like to use a mouse pointer to select a cell in a table created by tkinter.treeview() and print out the cell's value. How can I do this?

Below is a sample code to create a tkinter.treeview table. In this case, I would like to use my mouse pointer to click on one of the values say "Airport". However, when I click that cell, the entire row (i.e. the widget item) is instead selected. How can I avoid this so that I can get what I want?

import tkinter as tk
import tkinter.ttk as ttk

class App(tk.Frame):
    def __init__(self, parent, *args, **kwargs):
        ttk.Frame.__init__(self, parent, *args, **kwargs)
        self.tree = ttk.Treeview(parent, columns=("size", "modified"))
        self.tree["columns"] = ("date", "time", "loc")

        self.tree.column("date", width=80)
        self.tree.column("time", width=80)
        self.tree.column("loc", width=100)

        self.tree.heading("date", text="Date")
        self.tree.heading("time", text="Time")
        self.tree.heading("loc", text="Loc")
        self.tree.bind('<ButtonRelease-1>', self.selectItem)

        self.tree.insert("","end",text = "Name",values = ("Date","Time","Loc"))
        self.tree.insert("","end",text = "John",values = ("2017-02-05","11:30:23","Airport"))
        self.tree.insert("","end",text = "Betty",values = ("2014-06-25","18:00:00","Orchard Road"))

        self.tree.grid()

    def selectItem(self, event):
        curItem = self.tree.focus()
        print (self.tree.item(curItem))


if __name__ == "__main__":
    window = tk.Tk()
    app = App(window)
    window.mainloop()
Sun Bear
  • 7,594
  • 11
  • 56
  • 102
  • You won't be able to highlight just a single cell, but you can get the value of the cell that was clicked on. Is that what you want? Have you looked through the documentation for the Treeview widget to learn about methods that help you learn what was clicked on? – Bryan Oakley Jan 15 '18 at 18:32
  • Yes that is what I want. Is `.identify_element(x, y)` the method? – Sun Bear Jan 15 '18 at 18:50
  • How do I get the x and y of the mouse pointer when not using a canvas? – Sun Bear Jan 15 '18 at 19:16
  • The event object that is passed to the callback has a `x` and `y` attribute. – Bryan Oakley Jan 15 '18 at 19:29
  • I figure that `x,y = self.tree.winfo_pointerxy()` could give the coordinates of the mouse pointer relative to widget's root window. However, I found that `.identify_element(x,y)` does not give the value of the clicked cell. Can you point me to the method I should be using? – Sun Bear Jan 15 '18 at 19:42
  • 1
    use the x,y from the event object. Those coordinates are relative to the widget. `pointerxy` returns the coordinates relative to the screen. – Bryan Oakley Jan 15 '18 at 20:00
  • I have changed to `x,y = event.x, event.y`, thanks. Still the have not found the right method to get the value of the clicked cell. – Sun Bear Jan 15 '18 at 20:13
  • 2
    The code you posted shows the values from all the columns of the selected item, and you now claim to have figured out which column the user clicked on. Put those two together. – Bryan Oakley Jan 15 '18 at 20:20

1 Answers1

10

Thanks to Bryan Oakley's guidance, I have revised the selectItem callback to:

def selectItem(self, event):
    curItem = self.tree.item(self.tree.focus())
    col = self.tree.identify_column(event.x)
    print ('curItem = ', curItem)
    print ('col = ', col)

    if col == '#0':
        cell_value = curItem['text']
    elif col == '#1':
        cell_value = curItem['values'][0]
    elif col == '#2':
        cell_value = curItem['values'][1]
    elif col == '#3':
        cell_value = curItem['values'][2]
    print ('cell_value = ', cell_value)

It gave me what I wanted. Hope this script will help any other asking the same question.

Sun Bear
  • 7,594
  • 11
  • 56
  • 102