Python Tkinter multiple selection Listbox

Question:

I have a listbox which is set up with selectmode='multiple'.
I then try to obtain a list of all the options the user has selected, by the code name.get(ACTIVE).
The problem is that it doesn’t always get all the options I have highlighted in the listbox GUI.

If I highlight one, it brings this back correctly.
If I highlight two or more (by a single click on each) it only returns the last item I selected
If I have multiple highlighted, but then click to un-highlight one, it’s this last one I clicked that gets returned even though it unhighlighted.

I’m expecting for the code to bring back what ever is highlighted.

The code to set up the listbox is:

self.rightBT3 = Listbox(Frame1,selectmode='multiple',exportselection=0)

The code to retrieve the selections is:

selection = self.rightBT3.get(ACTIVE)

This is a screenshot of what the Application looks like in action, at the top you can see the console only registered the one selection (last one I clicked).

enter image description here

Asked By: Zenettii

||

Answers:

It seems the correct way to get a list of selected items in a Tkinter listbox is to use self.rightBT3.curselection(), which returns a tuple containing the zero-based index of the selected lines. You can then get() each line using those indices.

(I haven’t actually tested this though)

Answered By: Tharwen

I find the above solution a little bit “obscure”. Specially when we are dealing here with programers that are learning the craft or learning python/tkinter.

I came out with, what I think, a more explanatory solution, which is the following. I hope that this works out better for you.

#-*- coding: utf-8 -*-
# Python version 3.4
# The use of the ttk module is optional, you can use regular tkinter widgets

from tkinter import *
from tkinter import ttk

main = Tk()
main.title("Multiple Choice Listbox")
main.geometry("+50+150")
frame = ttk.Frame(main, padding=(3, 3, 12, 12))
frame.grid(column=0, row=0, sticky=(N, S, E, W))

valores = StringVar()
valores.set("Carro Coche Moto Bici Triciclo Patineta Patin Patines Lancha Patrullas")

lstbox = Listbox(frame, listvariable=valores, selectmode=MULTIPLE, width=20, height=10)
lstbox.grid(column=0, row=0, columnspan=2)

def select():
    reslist = list()
    seleccion = lstbox.curselection()
    for i in seleccion:
        entrada = lstbox.get(i)
        reslist.append(entrada)
    for val in reslist:
        print(val)

btn = ttk.Button(frame, text="Choices", command=select)
btn.grid(column=1, row=1)

main.mainloop()

Please note that the use ot the ttk themed widgets is completely optional. You can use normal tkinter’s widgets.

Answered By: Enrique Boeneker

To get a list of text items selected in a listbox, I find the below solution to be the most elegant:

selected_text_list = [listbox.get(i) for i in listbox.curselection()]
Answered By: nanogoats

I too came across the same problem. After some research I’ve come to a somewhat workable solution that allows for multiple selections to be made in a Listbox. It’s not ideal, in that a scrollbar is still missing from the field (a UX clue that there are additional values). However, it does allow for multi-selections.

from tkinter import *
window_app = Tk()


# ### Allows for multi-selections ###
def listbox_used(event):
    curselection = listbox.curselection()
    for index in curselection:
        print(listbox.get(index))  # Gets current selection from listbox
        # Only challenge with this implementation is the incremental growth of the list.
        # However, this could be resolved with a Submit button that gets the final selections.


listbox = Listbox(window_app, height=4, selectmode='multiple')
fruits = ["Apple", "Pear", "Orange", "Banana", "Cherry", "Kiwi"]
for item in fruits:
    listbox.insert(fruits.index(item), item)
listbox.bind("<<ListboxSelect>>", listbox_used)  # bind function allows any selection to call listbox_used function.
listbox.pack(padx=10, pady=10)  # Adds some padding around the field, because...fields should be able to breathe :D

window_app.mainloop()
Answered By: Carewen
Categories: questions Tags: ,
Answers are sorted by their score. The answer accepted by the question owner as the best is marked with
at the top-right corner.