Search code examples
pythonpygtkgtktreeview

How to render custom columns with a GenericTreeModel


I have to display some data in a treeview. The "real" data model is huge and I cannot copy all the stuff in a TreeStore, so I guess I should use a GenericTreeModel to act like a virtual treeview. Btw, the first column is the classic icon+text style and I think I should declare a column with a CellRendererPixbuf (faq sample), but I'm not sure what the model methods on_get_n_columns() and on_get_value() should return. It's both a Pixbuf and a string value for the same column.


Solution

  • Look at the tutorial, there is an example that packs two cell renderer to one column. The difference is that you are using a custom tree model and the behavior depends on how you modeled your model. If you have one column with the text and one column with the pixbuf you can use set_attributes:

    column = gtk.TreeViewColumn('Pixbuf and text')
    cell1 = gtk.CellRenderText()
    cell2 = gtk.CellRenderPixbuf()
    column.pack_start(cell1, True)
    column.pack_start(cell2, False)
    column.set_attribute(cell1, 'text', 0) # the first column contains the text
    column.set_attribute(cell2, 'pixbuf', 1) # the second column contains the pixbuf
    

    You can have otherwise a tree model with just one column with the objects that contains all you need, so just set a callback:

    class MyObject:
        def __init__(self, text, pixbuf):
            self.text = text
            self.pixbuf = pixbuf
    
    def cell1_cb(col, cell, model, iter):
        obj = model.get_value(iter)
        cell.set_property('text', obj.text)
    
    def cell2_cb(col, cell, model, iter):
        obj = model.get_value(iter)
        cell.set_property('pixbuf', obj.pixbuf)
    
    column = gtk.TreeViewColumn('Pixbuf and text')
    cell1 = gtk.CellRenderText()
    cell2 = gtk.CellRenderPixbuf()
    column.pack_start(cell1, True)
    column.pack_start(cell2, False)
    column.set_cell_data_func(cell1, cell1_cb)
    column.set_cell_data_func(cell2, cell2_cb)
    

    I hope I give you an idea of what you can do and a start point. Disclaimer: I did not test the code.