Table of Contents
The TreeView widget displays lists and trees displaying multiple columns. It replaces the previous set of List, CList, Tree and CTree widgets with a much more powerful and flexible set of objects that use the Model-View-Controller (MVC) principle to provide the following features:
Of course, all this capability comes at the price of a significantly more complex set of objects and interfaces that appear overwhelming at first. In the rest of this chapter we'll explore the TreeView objects and interfaces to reach an understanding of common usage. The more esoteric aspects, you'll have to explore on your own.
We'll start with a quick overview tour of the objects and interfaces and then dive into the TreeModel interface and the predefined ListStore and TreeStore classes.
A TreeView widget is the user interface object that displays the data stored in an object that implements the TreeModel interface. Two base tree model classes are provided in PyGTK 2.0:
The two additional tree models stack on top of (or interpose on) the base models:
A TreeView displays all of the rows of a TreeModel but may display only some of the columns. Also the columns may be presented in a different order than the TreeModel stores them.
The TreeView uses TreeViewColumn objects to organize the display of the columnar data. Each TreeViewColumn displays one column with an optional header that may contain the data from several TreeModel columns. The individual TreeViewColumns are packed (similar to HBox containers) with CellRenderer objects to render the display of the associated data from a TreeModel row and column location. There are three predefined CellRenderer classes:
A TreeViewColumn can contain several CellRenderer objects to provide a column that, for example, may have an image and text packed together.
Finally, the TreeIter, TreeRowReference and TreeSelection objects provide a transient pointer to a row in a TreeModel, a persistent pointer to a row in a TreeModel and an object managing the selections in a TreeView.
A TreeView display is composed using the following general operations not necessarily in this order:
The example program basictreeview.py illustrates the creation and display of a simple TreeView:
| 
    1   #!/usr/bin/env python
    2
    3   # example basictreeview.py
    4
    5   import pygtk
    6   pygtk.require('2.0')
    7   import gtk
    8
    9   class BasicTreeViewExample:
   10
   11       # close the window and quit
   12       def delete_event(self, widget, event, data=None):
   13           gtk.main_quit()
   14           return False
   15
   16       def __init__(self):
   17           # Create a new window
   18           self.window = gtk.Window(gtk.WINDOW_TOPLEVEL)
   19
   20           self.window.set_title("Basic TreeView Example")
   21
   22           self.window.set_size_request(200, 200)
   23
   24           self.window.connect("delete_event", self.delete_event)
   25
   26           # create a TreeStore with one string column to use as the model
   27           self.treestore = gtk.TreeStore(str)
   28
   29           # we'll add some data now - 4 rows with 3 child rows each
   30           for parent in range(4):
   31               piter = self.treestore.append(None, ['parent %i' % parent])
   32               for child in range(3):
   33                   self.treestore.append(piter, ['child %i of parent %i' %
   34                                                 (child, parent)])
   35
   36           # create the TreeView using treestore
   37           self.treeview = gtk.TreeView(self.treestore)
   38
   39           # create the TreeViewColumn to display the data
   40           self.tvcolumn = gtk.TreeViewColumn('Column 0')
   41
   42           # add tvcolumn to treeview
   43           self.treeview.append_column(self.tvcolumn)
   44
   45           # create a CellRendererText to render the data
   46           self.cell = gtk.CellRendererText()
   47
   48           # add the cell to the tvcolumn and allow it to expand
   49           self.tvcolumn.pack_start(self.cell, True)
   50
   51           # set the cell "text" attribute to column 0 - retrieve text
   52           # from that column in treestore
   53           self.tvcolumn.add_attribute(self.cell, 'text', 0)
   54
   55           # make it searchable
   56           self.treeview.set_search_column(0)
   57
   58           # Allow sorting on the column
   59           self.tvcolumn.set_sort_column_id(0)
   60
   61           # Allow drag and drop reordering of rows
   62           self.treeview.set_reorderable(True)
   63
   64           self.window.add(self.treeview)
   65
   66           self.window.show_all()
   67
   68   def main():
   69       gtk.main()
   70
   71   if __name__ == "__main__":
   72       tvexample = BasicTreeViewExample()
   73       main()
 | 
In real programs the TreeStore would likely be populated with data after the TreeView is displayed due to some user action. We'll look at the details of the TreeView interfaces in more detail in the sections to come. Figure 14.1, “Basic TreeView Example Program” shows the window created by the basictreeview.py program after a couple of parent rows have been expanded.
Next let's examine the TreeModel interface and the models that implement it.