|
TreeViewColumns and CellRenderers work together to display a column of data in a TreeView. The TreeViewColumn provides the column title and a vertical space for the CellRenderers to render a portion of the data from the TreeView data store. A CellRenderer handles the rendering of each row and column data within the confines of the TreeViewColumn. A TreeViewColumn can contain more than one CellRenderer to provide a row display similar to an HBox. A common use of multiple CellRenderers is to combine a CellRendererPixbuf and a CellRendererText in one column. An example illustrating the layout of two TreeViewColumns: one with two CellRenderers and one with one CellRenderer is shown in Figure 14.2, “TreeViewColumns with CellRenderers”: The application of each CellRenderer is indicated with a different background color: yellow for the CellRendererPixbuf, cyan for one CellRendererText, and pink for the other CellRendererText. Note that the CellRendererPixbuf and the first CellRendererText are in the same column headed by the "Pixbuf and Text" header. The background color of the CellRendererText rendering "Print File" is the default color to show the application area in a single row. Figure 14.2, “TreeViewColumns with CellRenderers” was created by the treeviewcolumn.py program. The type of CellRenderer needed is determined by the type of tree model data display required; PyGTK has three pre-defined CellRenderers:
The properties of a CellRenderer determine how the data will be rendered:
The above properties are available for all CellRenderer subclasses. The individual CellRenderer types also have their own properties. The CellRendererPixbuf has these properties:
The CellRendererText has a large number of properties mostly dealing with style specification:
Almost every CellRendererText property has an associated boolean property (with the "-set" suffix) that indicates if the property is to be applied. This allows you to set a property globally and selectively enable and disable its application. The CellRendererToggle has the following properties:
The properties can be set for all rows by using the gobject.set_property() method. See the treeviewcolumn.py program for an example using this method. An attribute associates a tree model column with a CellRenderer property; the CellRenderer sets the property from the row's column value before rendering the cell. This allows you to customize the cell display using tree model data. An attribute can be added to the current set by using:
where the property specified by attribute is set for the cell_renderer from column. For example:
sets the CellRenderer background to the color specified by the string in the second column of the data store. To clear all attributes and set several new attributes at once use:
where the attributes of cell_renderer are set by key-value pairs: property=column. For example, for a CellRendererText:
sets, for each row, the text from the first column, the background color from the second column and the horizontal padding from the fourth column. See the treeviewcolumn.py program for an example using these methods. The attributes of a CellRenderer can be cleared using:
If setting attributes is not sufficient for your needs you can set a function to be called for each row to set the properties for that CellRenderer using:
where func has the signature:
where column is the TreeViewColumn containing cell_renderer, tree_model is the data store and iter is a TreeIter pointing at a row in tree_model. user_data is the value of data that was passed to set_cell_data_func(). In func you set whatever properties you want on cell_renderer. For example the following code fragment sets the text property to display PyGTK objects as an ID string.
The resulting display should be something like Figure 14.3, “CellRenderer Data Function”: Another use of a cell data function is to control the formatting of a numerical text display e.g. a float value. A CellRendererText will display and automatically convert a float to a string but with a default format "%f". With cell data functions you can even generate the cell data for the columns from external data. For example the filelisting.py program uses a ListStore with just one column that holds a list of file names. The TreeView displays columns that include a pixbuf, the file name and the file's size, mode and time of last change. The data is generated by the following cell data functions:
These cell data functions retrieve the file information using the name, extract the needed data and set the cell 'text' or 'pixbuf' property with the data. Figure 14.4, “File Listing Example Using Cell Data Functions” shows the example program in action: A CellRendererText can use Pango markup (by setting the "markup" property) instead of a plain text string to encode various text attributes and provide a rich text display with multiple font style changes. See the Pango Markup reference in the PyGTK Reference Manual for details on the Pango markup language. The following code fragment illustrates the use of the "markup" property:
produces a display similar to Figure 14.5, “CellRendererText Markup”: If you create pango markup on the fly you have to be careful to replace the characters that are special to the markup language: "<", ">", "&". The Python library function cgi.escape() can do these basic conversions. CellRendererText cells can be made editable to allow a user to edit the contents of the cell that is selected by clicking it or pressing one of the Return, Enter, Space or Shift+Space keys. A CellRendererText is made editable for all rows by setting its "editable" property to TRUE as follows:
Individual cells can be set editable by adding an attribute to the TreeViewColumn using the CellRendererText similar to:
which sets the "editable" property to the value contained in the third column of the data store. Once the cell editing completes, your application should handle the "edited" signal to retrieve the new text and set the associated data store value. Otherwise the cell value reverts to its original value. The signature of the "edited" signal handler is:
where cell is the CellRendererText, path is the tree path (as a string) to the row containing the edited cell, new_text is the edited text and user_data is context data. Since the TreeModel is needed to use path to set new_text in the data store you probably want to pass the TreeModel as user_data in the connect() method:
If you have two or more editable cells in a row, you could pass the TreeModel column number as part of user_data as well as the TreeModel:
Then you can set the new text in the "edited" handler similar to this example using a ListStore:
CellRendererToggle buttons can be made activatable by setting the "activatable" property to TRUE. Similar to editable CellRendererText cells the "activatable" property can be set for the entire CellRendererToggle set of cells using the set_property() method or for individual cells by adding an attribute to the TreeViewColumn containing the CellRendererToggle.
The setting of the individual toggle buttons can be derived from the values in a TreeModel column by adding an attribute, for example:
You should connect to the "toggled" signal to get notification of user clicks on the toggle buttons so that your application can change the value in the data store. For example:
The callback has the signature:
where path is the tree path, as a string, pointing to the row containing the toggle that was clicked. You should pass the TreeModel and possibly the column index as part of user_data to provide the necessary context for setting the data store values. For example, your application can toggle the data store value as follows:
If your application wants to display the toggle buttons as radio buttons and have only one be set, it will have to scan the data store to deactivate the active radio button and then set the toggled button. For example:
takes the lazy approach of setting all data store values to FALSE before setting the value to TRUE for the row specified by path. The cellrenderer.py program illustrates the application of editable CellRendererText and activatable CellRendererToggle cells in a TreeStore.
The program provides editable cells in the first column and activatable cells in the second column. Lines 64-66 create an editable CellRendererText and connect the "edited" signal to the col0_edited_cb() callback (lines 87-94) that changes the appropriate row column value in the TreeStore. Likewise lines 70-72 create an activatable CellRendererToggle and connect the "toggled" signal to the col1_toggled_cb() callback (lines 95-101) to change the appropriate row value. When an editable or activatable cell is changed, a message is printed to indicate what the change was. Figure 14.6, “Editable and Activatable Cells” illustrates the cellrenderer.py program in operation. |