Python Forum
[Tkinter] listbox selection
Thread Rating:
  • 0 Vote(s) - 0 Average
  • 1
  • 2
  • 3
  • 4
  • 5
[Tkinter] listbox selection
#2
The info is not sorted, it is just generated fresh each time you call curselection(). The listbox has no memory of selection order, only what is selected. If selection order is important, you will need to update the list choices to reflect the order. That will give you a chronological list and provide feedback to the user. Something like this:
import tkinter as tk

class OrderedListbox(tk.Listbox):
    """A list box that moves unselected items below selected items"""
    UNSPECIFIED = object()

    def __init__(self, *args, items=None, command=None, **kvargs):
        super().__init__(*args, selectmode=tk.MULTIPLE, **kvargs)
        self.bind('<<ListboxSelect>>', self._update)
        self.config(items=items, command=command)

    def config(self, items=UNSPECIFIED, command=UNSPECIFIED, **kvargs):
        """
        Implement items and command options.
        items=iterable : Use to set list items
        command=callable : Use to set function called when selection changes
        """
        if items is not self.UNSPECIFIED:
            self._items = items or []
            self.delete(0, tk.END)
            self.insert(tk.END, *self._items)
        if command is not self.UNSPECIFIED:
            self.command = command

    def _update(self, _):
        """Callback function when user changes selection"""
        # Get list of selected items
        selection = self.selection()

        # Move unselected items after selected items
        items = selection + [item for item in self._items if item not in selection]
        self.config(items=items)
        if len(selection) > 0:
            self.selection_set(0, len(selection)-1)
        else:
            super().selection_clear(0, tk.END)

        # Execute callback function with currently selected items
        if self.command is not None:
            self.command(self.selection())

    def selection_clear(self):
        """Clear selection"""
        super().selection_clear(0, tk.END)

    def selection(self):
        """Return list of selected items"""
        return [self.get(i) for i in self.curselection()]

class MainWindow(tk.Tk):
    def __init__(self, *args, **kvargs):
        super().__init__(*args, **kvargs)
        self.list = OrderedListbox(self, items=list('ABCDEFG'), width=5)
        self.list.pack(padx=10, pady=10)
        button = tk.Button(self, text="Clear", command=self.list.selection_clear)
        button.pack(padx=10, pady=10)

window = MainWindow()
window.list.config(command=lambda x:print(x))
window.mainloop()
Usually I see two lists when the the interface supports order AND selection. There is a list for selecting items and a second list for ordering the selected items, and some buttons for moving values in and out of the selected items list.
Reply


Messages In This Thread
listbox selection - by DPaul - May-16-2022, 09:30 AM
RE: listbox selection - by deanhystad - May-16-2022, 05:14 PM
RE: listbox selection - by DPaul - May-16-2022, 05:32 PM
RE: listbox selection - by deanhystad - May-16-2022, 06:12 PM
RE: listbox selection - by DPaul - May-17-2022, 06:38 AM

Forum Jump:

User Panel Messages

Announcements
Announcement #1 8/1/2020
Announcement #2 8/2/2020
Announcement #3 8/6/2020