Piyush Chatterjee
Piyush Chatterjee

Reputation: 117

Selecting multiple rows and fetching them simultaneously in treeview in tkinter

How can I select multiple rows in a treeview where in the treeview is pulling up data from MySQL database, so that I can display them in my text box. I am able to do this for one row at a time but not sure on how to select multiple entries. I basically have 2 frames in my GUI, left and right frames. Left frame shows a treeview with the animal names and right frame shows a text box. When someone selects the animal name and hit Add button, it should be added into the right text box. Just want to figure out on how to do this for multiple selections. Below is my code so far.

from tkinter import *
from tkinter import ttk
import pymysql


class Animals_App:
    def __init__(self, root):
        self.root = root
        self.root.title("Animals")
        self.root.geometry("1350x750+0+0")
        self.root.resizable(FALSE, FALSE)
        title = Label(self.root, text="Animals", font=("times new roman", 30, "bold"), bg="#262626",
                      fg="white").place(x=0, y=0, relwidth=1)
        self.root.config(background="powder blue")

        # =====Variables========


        self.animal_var = StringVar()

        # ==For displaying added Animal names on the right text box
        def display_name():
            txt_box.insert(END, 'Animal : ' + self.animal_var.get() + '\n')

        # ==========Frame 1 (Left Frame)===========
        Top_Frame = Frame(self.root, bd=5, relief=RIDGE, bg="white")
        Top_Frame.place(x=10, y=50, width=750, height=620)
        Addbtn = Button(Top_Frame, padx=16, pady=1, bd=7, fg='black', font=('arial', 16, 'bold'), width=4,
        text='Add', bg='powder blue', command=display_name).grid(row=0, column=0)

        Table_Frame = Frame(self.root, bd=5, relief=RIDGE, bg="white")
        Table_Frame.place(x=10, y=130, width=750, height=620)

        scroll_x = Scrollbar(Table_Frame, orient=HORIZONTAL)
        scroll_y = Scrollbar(Table_Frame, orient=VERTICAL)

        self.Animals_table = ttk.Treeview(Table_Frame,
                                          columns=("animal"),
                                          xscrollcommand=scroll_x.set, yscrollcommand=scroll_y.set)
        scroll_x.pack(side=BOTTOM, fill=X)
        scroll_y.pack(side=RIGHT, fill=Y)
        scroll_x.config(command=self.Animals_table.xview)
        scroll_y.config(command=self.Animals_table.yview)

        self.Animals_table.heading("animal", text="Animal Names")
        self.Animals_table['show'] = 'headings'

        self.Animals_table.column("animal", width=100)

        self.Animals_table.pack(fill=BOTH, expand=1)

        self.Animals_table.bind("<ButtonRelease-1>", self.get_cursor)
        self.fetch_data()

        # ==========Frame 2 (Right Frame)===========
        Txt_Frame = Frame(self.root, bd=5, relief=RIDGE, bg="white")
        Txt_Frame.place(x=770, y=70, width=580, height=620)

        scroll_y = Scrollbar(Txt_Frame, orient=VERTICAL)
        scroll_y.pack(fill=Y, side=RIGHT)

        txt_box = Text(Txt_Frame, font=("times new roman", 15), bg="lightyellow", fg="black",
                       yscrollcommand=scroll_y.set)
        txt_box.pack(fill=BOTH, expand=1)
        scroll_y.config(command=txt_box.yview)

        # txt_box.insert(END, 'Animal : ' + '\n')

    def fetch_data(self):
        con = pymysql.connect(host="localhost", user="root", password="", database="animaltree")
        cur = con.cursor()
        cur.execute("select * from animals")
        rows = cur.fetchall()
        # rows=["Cow","Deer","Dog","Zebra"]
        if len(rows) != 0:
            self.Animals_table.delete(*self.Animals_table.get_children())
            for row in rows:
                self.Animals_table.insert('', END, values=row)
            con.commit()
        con.close()

    def get_cursor(self, ev):
        cursor_row = self.Animals_table.focus()
        contents = self.Animals_table.item(cursor_row)
        row = contents['values']
        self.animal_var.set(row[0])


root = Tk()
obj = Animals_App(root)
root.mainloop()

Upvotes: 1

Views: 932

Answers (1)

acw1668
acw1668

Reputation: 46669

The default selection mode of Treeview is already in multiple mode. You need to use .selection() instead of .focus() to get the selected items.

In order to save the selections, change self.animal_var from StringVar() to Variable() and update display_name() and self.get_cursor() as below:

class Animals_App:
    def __init__(self, root):
        ...
        self.animal_var = Variable()  # changed from StringVar()

        def display_name():
            txt_box.insert(END, 'Animal : ' + ', '.join(self.animal_var.get()) + '\n')

        ...

    def get_cursor(self, ev):
        self.animal_var.set([ev.widget.item(idx)['values'][0] for idx in ev.widget.selection()])

Upvotes: 2

Related Questions