Table of Contents
TreeView widget displays lists and trees
displaying multiple columns. It replaces the previous set of List,
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
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:
TreeStorethat provides hierarchical data storage organized as tree rows with columnar data. Each tree row can have zero or more child rows. All rows must have the same number of columns.
ListStorethat provides tabular data storage organized in rows and columns similar to a table in a relational database. The
ListStoreis really a simplified version of a
TreeStorewhere the rows have no children. It has been created to provide a simpler (and presumably more efficient) interface to this common data model. And,
The two additional tree models stack on top of (or interpose on) the base models:
TreeModelSortthat provides a model where the data of the underlying tree model is maintained in a sorted order. And,
TreeModelFilterthat provides a model containing a subset of the data in the underlying model. Note this model is available only in PyGTK 2.4 and above.
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
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
CellRendererPixbufthat renders a pixbuf image into the cells of a
CellRendererTextthat renders a string into the cells of a
TreeViewColumn. It will convert the column data to a string format if needed i.e. if displaying a model column containing float data, the
CellRendererTextwill convert it to a string before rendering it.
CellRendererTogglethat renders a boolean value as a toggle button into the cells of a
TreeViewColumn can contain several
CellRenderer objects to provide a column that, for
example, may have an image and text packed together.
TreeSelection objects provide a transient pointer to
a row in a
TreeModel, a persistent pointer to a row
TreeModel and an object managing the selections
TreeView display is composed using the
following general operations not necessarily in this order:
TreeStorewith one or more columns of a specified data type.
TreeViewwidget is created and associated with the tree model.
TreeViewColumns are created and inserted in the
TreeView. Each of these will present a single display column.
TreeViewColumnone or more
CellRenderers are created and added to the
CellRendererare set to indicate from which column of the tree model to retrieve the attribute data. for example the text to be rendered. This allows the
CellRendererto render each column in a row differently.
TreeViewis inserted and displayed in a
TreeViewwill automatically track the changes.
The example program basictreeview.py
illustrates the creation and display of a simple
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
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
program after a couple of parent rows have been expanded.
Next let's examine the
and the models that implement it.