pythonlistboxpygtkgtk2

How do I make a GTK 2 list with multiple selection?


In a GTK 3 release, the ListBox widget added supported for multiple elements being selected from the list:

I'd like to achieve the same effect with GTK 2. I'm considering using a ScrolledWindow with a VBox of CheckButton's. I fear it's not going to look very good though; like this, but with a scrollbar:

Does anyone know a good way to emulate the functionality in the first image using GTK 2?


Solution

  • It turns out there was a method of doing just this buried in the documentation! In fact, you should find it all the way back to GTK 2.0, but the selection constant might have had a different name (SELECTION_MULTI).

    The widget looks like this:

    A user interface with a list showing multiple elements selected

    The color scheme is inherited from my GNOME theme, so don't mind the window styling too much. This widget works with both Ctrl and Shift keys. It doesn't automatically have multiple selection just clicking on the different items.

    Here's the (Python 2) MWE I made for this:

    import gtk
    
    
    class UI(gtk.Window):
        def __init__(self):
            gtk.Window.__init__(self)
            self.set_position(gtk.WIN_POS_CENTER)
            self.set_default_size(250, 150)
    
            store = gtk.ListStore(str)
            for i in range(7):
                # The list notation here is odd, but required.
                store.append(["Item %d" % i])
    
            tree_view = gtk.TreeView()
            tree_view.set_model(store)
    
            # The view can support a whole tree, but we want just a list.
            renderer = gtk.CellRendererText()
            column = gtk.TreeViewColumn("Multiple Selection", renderer, text=0)
            tree_view.append_column(column)
    
            # This is the part that enables multiple selection.
            tree_view.get_selection().set_mode(gtk.SELECTION_MULTIPLE)
    
            scrolled_tree = gtk.ScrolledWindow()
            scrolled_tree.set_policy(gtk.POLICY_AUTOMATIC, gtk.POLICY_ALWAYS)
            scrolled_tree.add_with_viewport(tree_view)
    
            self.add(scrolled_tree)
    
    
    def main():
        win = UI()
        win.connect("destroy", gtk.main_quit)
        win.show_all()
        gtk.main()
    
    
    if __name__ == "__main__":
        main()