1

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()
5
  • You mean you want to choose multiple items from treeview? Commented Apr 21, 2021 at 20:39
  • @CoolCloud Yes that is correct. Commented Apr 21, 2021 at 21:21
  • Use selectmode='multiple' ? as an option for treeview. Commented Apr 21, 2021 at 21:28
  • 1
    The default selection mode of Treeview is already in multiple. You need to use .selection() instead of .focus() to get the selected items. Commented Apr 21, 2021 at 23:54
  • @acw1668 Thanks for your answer. Another question, what would be best way to store the multiple variables in this case. For single selection this was what I was doing: self.animal_var.set(row[0]) Commented Apr 22, 2021 at 0:23

1 Answer 1

2

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

Comments

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.