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 TreeStore that 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.
- the ListStore that provides tabular
data storage organized in rows and columns similar to a table in a
relational database. The ListStore is really a
simplified version of a TreeStore where 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:
- the TreeModelSort that provides a
model where the data of the underlying tree model is maintained in a sorted
order. And,
- the TreeModelFilter that 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.
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:
- the CellRendererPixbuf that renders
a pixbuf image into the cells of a
TreeViewColumn.
- the CellRendererText that 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
CellRendererText will convert it to a string before
rendering it.
- the CellRendererToggle that renders
a boolean value as a toggle button into the cells of a
TreeViewColumn.
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:
- A tree model object is created usually a
ListStore or TreeStore with
one or more columns of a specified data type.
- The tree model may be populated with one or more rows of
data.
- A TreeView widget is created and
associated with the tree model.
- One or more TreeViewColumns are
created and inserted in the TreeView. Each of these
will present a single display column.
- For each TreeViewColumn one or more
CellRenderers are created and added to the
TreeViewColumn.
- The attributes of each CellRenderer
are 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
CellRenderer to render each column in a row
differently.
- The TreeView is inserted and
displayed in a Window or
ScrolledWindow.
- The data in the tree model is manipulated programmatically
in response to user actions. The TreeView will
automatically track the changes.
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.