Question

I have a project going where I need to have a list of data, and you should only be able to select two items in the list. I'm very new to python and Gtk, but my searches has been in vain for an answer for how to do this. So, the code.

#!/usr/bin/python3

from gi.repository import Gtk

class Window(Gtk.Window):

    def __init__(self):
        Gtk.Window.__init__(self, title="MyWindow")

        self.set_default_size(200, 200)

        self.liststore = Gtk.ListStore(str, str)
        for i in range(1,10):
            row = "Row"+ str(i)
            value = "Value"+str(i)
            self.liststore.append([row, value])


        treeview = Gtk.TreeView(model=self.liststore)

        renderer_text = Gtk.CellRendererText()
        column = Gtk.TreeViewColumn("Col1", renderer_text, text=0)
        treeview.append_column(column)

        column = Gtk.TreeViewColumn("Col2", renderer_text, text=1)
        treeview.append_column(column)

        treeview.get_selection().set_mode(Gtk.SelectionMode.MULTIPLE)
        #treeview.get_selection().set_select_function() <-- How do you write one of these?

        self.add(treeview)

win = Window()
win.connect("delete-event", Gtk.main_quit)
win.show_all()
Gtk.main()

Obviously, since I want to limit the number of selections, Gtk.SelectionMode.MULTIPLE won't work. But I have found that you can specify your own selectionmode with set_select_function(). I have however not found any example of how to write one of those, or what they need to contain. I have written the same sort of function in Java for a JList (started the project in Java but had to switch language due to limitations in the language [scanning for wifi]) and I can post that code if needed for some reason.

So, my question is this: How do you actually write a select function for a TreeSelection in python? I'm using Python 3 and Gtk3.

Bonus question: How do you write it so you can limit the number of selections?

Was it helpful?

Solution

A little late but better than never. .set_select_function() in this scenario requires a function name as the argument. The function then returns True if the row can be toggled, or False if not. You must also leave the TreeSelection mode as Gtk.SelectionMode.MULTIPLE.

#!/usr/bin/python3

from gi.repository import Gtk

class Window(Gtk.Window):

def __init__(self):
    Gtk.Window.__init__(self, title="MyWindow")

    self.set_default_size(200, 200)

    self.liststore = Gtk.ListStore(str, str)
    for i in range(1,10):
        row = "Row"+ str(i)
        value = "Value"+str(i)
        self.liststore.append([row, value])


    treeview = Gtk.TreeView(model=self.liststore)

    renderer_text = Gtk.CellRendererText()
    column = Gtk.TreeViewColumn("Col1", renderer_text, text=0)
    treeview.append_column(column)

    column = Gtk.TreeViewColumn("Col2", renderer_text, text=1)
    treeview.append_column(column)

    treeview.get_selection().set_mode(Gtk.SelectionMode.MULTIPLE)
    treeview.get_selection().set_select_function(self.select_function)

    self.add(treeview)

def select_function(self, treeselection, model, path, current):
    state = True

    if treeselection.count_selected_rows() < 2:
        state = True
    else:
        if treeselection.path_is_selected(path):
            state = True
        else:
            state = False

    return state

win = Window()
win.connect("delete-event", Gtk.main_quit)
win.show_all()
Gtk.main()

Doing the above might not be the most discoverable way for users and an alternative may be to use CellRendererToggle widgets which throws an error if more than two are selected or simply doesn't allow the user to continue.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top