python treeview toggle

Had this post sitting around. Seems finished. May be helpful to someone. /me waves Wand of Publish +1

I was confused when I was playing around with this basic concept: adding a toggle widget to the treeview in pygtk. The reason for this is an inconsistency in the api model – or at least how I perceived it. With a regular toggle button, you create the widget and can manipulate it once it is drawn. The checkmark is toggled and the “toggled” signal is emitted. I only connect a signal handler to the toggled signal after. However, following this same logic, I created a list with a column of toggle widgets and tried clicking them… but nothing happened. The problem here was the toggled value was linked to the list’s data, and the data wasn’t actually changing. Even though the toggle signal was being emitted, the checkmark wasn’t being toggled because the data wasn’t changing, so I thought there was a problem with my code and the signal wasn’t being emitted. But actually, it would make more sense if it was a “clicked” signal that was being emitted, not the “toggled” signal.

Example source code:

#!/usr/bin/env python

# example basictreeviewtoggle.py

import pygtk
pygtk.require('2.0')
import gtk
import gobject

class BasicTreeViewToggleExample:

    # close the window and quit
    def delete_event(self, widget, event, data=None):
        gtk.main_quit()
        return False

    def column_toggled(self, cell, path, model):
        # get toggled iter, and value at column 0
        iter = model.get_iter((int(path),))
        val = model.get_value(iter, 0)

        # toggle the value
        val = not val

        # set new value
        model.set(iter, 0, val)


    def __init__(self):
        # create a new window
        self.window = gtk.Window(gtk.WINDOW_TOPLEVEL)
        self.window.set_title("Basic TreeView Toggle Example")
        self.window.set_size_request(200, 200)
        self.window.connect("delete_event", self.delete_event)

        # create a ListStore with two columns to use as the model
        self.model = gtk.ListStore(gobject.TYPE_BOOLEAN, str)

        # create some list items
        for item in range(5):
            self.model.append([False, 'item %i' % item])

        # create the TreeView using the model
        self.view = gtk.TreeView(self.model)

        # create a CellRendererText to render the data
        self.cellrenderer_text = gtk.CellRendererText()
        self.cellrenderer_toggle = gtk.CellRendererToggle()
        self.cellrenderer_toggle.connect('toggled', self.column_toggled, self.model)

        # create the TreeViewColumns to display the data
        self.tvcolumntext = gtk.TreeViewColumn('TreeViewColumn 1')
        self.tvcolumntoggle = gtk.TreeViewColumn('tog', self.cellrenderer_toggle, active=0)

        # add the TreeViewColumns to the TreeView
        self.view.append_column(self.tvcolumntoggle)
        self.view.append_column(self.tvcolumntext)




        # add the cell to the tvcolumn and allow it to expand
        self.tvcolumntoggle.pack_start(self.cellrenderer_toggle, False)
        self.tvcolumntext.pack_start(self.cellrenderer_text, True)

        
        # set the cell "text" attribute to column 0 - retrieve text
        # from that column in treestore
        self.tvcolumntext.add_attribute(self.cellrenderer_text, 'text', 1)


        
        # make it searchable
        self.view.set_search_column(1)

        # Allow sorting on the column
        self.tvcolumntext.set_sort_column_id(1)

        # Allow drag and drop reordering of rows
        self.view.set_reorderable(True)

        self.sw = gtk.ScrolledWindow()
        self.sw.add(self.view)
        self.window.add(self.sw)

        self.window.show_all()

def main():
    gtk.main()

if __name__ == "__main__":
    tvexample = BasicTreeViewToggleExample()
    main()

Leave a comment

Your email address will not be published. Required fields are marked *