Search code examples
pythonpygtkgtktreeview

Getting the checkboxes toggling in a GtkTreeView


I am using a treeview with checkboxes. I want the user to be able to click a checkbox and it will add that item to a favourites list. But currently I cannot get the boxes to toggle at all. Here's my code:

def draw_columns(self,treeview):
    self.ren = gtk.CellRendererToggle()
    self.ren.connect('toggled',self.on_toggle,treeview.get_model())
    self.tvfav = gtk.TreeViewColumn('Fav',self.ren,text=7)
    for i in [self.tvfav,'andall the other columns']:
        treeview.append_column(i)

 def on_toggle(self,cell,path_str,model):
    toggle_item = model.get_value(iter,column)
    toggle_item = not toggle_item
 # This method didn't work either
 ## model[path_str][1] = not model[path_str][1]
    if toggle_item:
        #Add it to the favourite list if it isn't already
        pass
    else:
        #remove it from the favourite list
        pass
    model.set(iter,column,toggle_item)   

def __init__(self):'
    ....
    self.liststore = gtk.ListStore(str,int, int, int,str, 'gboolean', str)
    self.treeview = gtk.TreeView(self.liststore)
    ....

What am I doing wrong that the boxes can't be checked? Also, how would I set the toggle when items are appended to the treeview like this:

if name in favourites:
    #Append to list with checkbox on
    self.liststore.append([name,x,y,z,ss,True,sss])

Solution

  • Disclaimer: I am confident this is not total bs, but can't test it at the moment.

    First, a CellRendererToggle wouldn't take a text property. second, if you would set it anyway, you wouldn't set it to column index 7 because you only have 7 column on the liststore (and index 7 would be the eigth column).

    You can see all available properties you can set for your renderer in the reference under 'Properties' (note also the inherited properties). Now, to set the property for each individual cell (per row) you can specify as you did, a keyword argument. So in your TreeviewColumn you would set this:

    # 5 is the index of bool in the liststore
    gtk.TreeViewColumn('Fav',renderer,active=5)
    

    Any attribute set like this is mapped to corresponding entry in the liststore. That means you can directy change it on the liststore or via a callback (on_toggle for instance).

    Edit:

    Maybe you have to set the mode property as well

    Edit 2:

    Here is a working example.

    import gtk
    
    
    def on_toggle(cell, path, model, *ignore):
        if path is not None:
            it = model.get_iter(path)
            model[it][0] = not model[it][0]
    
    model = gtk.ListStore(bool)
    tv = gtk.TreeView(model)
    
    cell = gtk.CellRendererToggle()
    cell.connect("toggled", on_toggle, model)
    col = gtk.TreeViewColumn("Foo", cell, active=0)
    tv.append_column(col)
    
    w = gtk.Window()
    w.connect("destroy", gtk.main_quit)
    w.show()
    
    w.add(tv)
    tv.show()
    
    ## Some initial data
    model.append([True])
    model.append([False])
    
    gtk.main()