Gtk2::TreeView
This is a meaty, beefy, big and bouncy section on the sometimes complex and misunderstood Gtk2::TreeView
and the classes used with it. It will start with a gentle introduction, and then move on to cover more intimate detail. Again, like the Gtk2::TextView
section, this one borrows heavily from the PyGtk tutorial.
The Gtk2::TreeView
widget is the user interface object that displays data stored in an object that implements the Gtk2::TreeModel
interface. Two base tree model classes are provided in Gtk2-Perl
:
Gtk2::TreeStore
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.
Gtk2::ListStore
provides tabular data storage organized in rows and columns similar to a table in a relational database. The Gtk2::ListStore
is really a simplified version of a Gtk2::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,
Gtk2::TreeModel
s stack on top of (or interpose on) the base models:
Gtk2::TreeModelSort
provides a model where the data of the underlying Gtk2::TreeModel
is maintained in a sorted order.
Gtk2::TreeModelFilter
that provides a model containing a subset of the data in the underlying Gtk2::TreeModel
.
A Gtk2::TreeView
displays all of the rows of a Gtk2::TreeModel
but may display only some of the columns. The columns may also be presented in a different order than that of the Gtk2::TreeModel
.
The Gtk2::TreeView
uses Gtk2::TreeViewColumn
objects to organize the display of the columnar data. Each Gtk2::TreeViewColumn
displays one column with an optional header that may contain the data from several Gtk2::TreeModel
columns. The individual Gtk2::TreeViewColumn
s are packed (similar to Gtk2::HBox
containers) with Gtk2::CellRenderer
objects to render the display of the associated data from a Gtk2::TreeModel
row and column location. There are five predefined Gtk2::CellRenderer
classes:
Gtk2::CellRendererPixbuf
- renders a pixbuf image into the cells of a Gtk2::TreeViewColumn
.
Gtk2::CellRendererText
- renders a string into the cells of a Gtk2::TreeViewColumn
.
Gtk2::CellRendererCombo
- A subclass of Gtk2::CellRendererText
, renders a Gtk2::ComboBox
into the cells of a Gtk2::TreeViewColumn
.
Gtk2::CellRendererToggle
- renders a boolean value as a toggle button into the cells of a Gtk2::TreeViewColumn
.
Gtk2::CellRendererProgress
- renders a progressbar into the cells of a Gtk2::TreeViewColumn
.
A Gtk2::TreeViewColumn
can contain several Gtk2::CellRenderer
objects to provide a column that, for example, may have an image and text packed together.
Finally, the Gtk2::TreeIter
, Gtk2::TreeRowReference
and Gtk2::TreeSelection
objects provide a transient pointer to a row in a Gtk2::TreeModel
; a persistent pointer to a row in a Gtk2::TreeModel
; and an object managing the selections in a Gtk2::TreeView
respectively.
A Gtk2::TreeView
display is composed using the following general operations not necessarily in this order:
A Gtk2::TreeModel
object is created usually a Gtk2::ListStore
or Gtk2::TreeStore
with one or more columns of a specified data type.
The Gtk2::TreeModel
may be populated with one or more rows of data.
A Gtk2::TreeView
widget is created and associated with the Gtk2::TreeModel
.
One or more Gtk2::TreeViewColumn
s are created and inserted in the Gtk2::TreeView
. Each of these will present a single display column.
For each Gtk2::TreeViewColumn
one or more Gtk2::CellRenderer
s are created and added to the Gtk2::TreeViewColumn
.
The attributes of each Gtk2::CellRenderer
are set to indicate from which column of the Gtk2::TreeModel
to retrieve the attribute data, EG: the text to be rendered. This allows the Gtk2::CellRenderer
to render each column in a row differently.
The Gtk2::TreeView
is inserted and displayed in a Gtk2::Window
or Gtk2::ScrolledWindow
.
The data in the Gtk2::TreeModel
is manipulated programmatically in response to user actions. The Gtk2::TreeView
will automatically track the changes.
Gtk2::TreeView
The program can be found here: 'Simple Gtk2::TreeView
Demo'
1 #! /usr/bin/perl -w 2 3 use strict; 4 use Gtk2 '-init'; 5 use Glib qw/TRUE FALSE/; 6 7 #standard window creation, placement, and signal connecting 8 my $window = Gtk2::Window->new('toplevel'); 9 $window->signal_connect('delete_event' => sub { Gtk2->main_quit; }); 10 $window->set_border_width(5); 11 $window->set_position('center_always'); 12 13 #this vbox will geturn the bulk of the gui 14 my $vbox = &ret_vbox(); 15 16 #add and show the vbox 17 $window->add($vbox); 18 $window->show(); 19 20 #our main event-loop 21 Gtk2->main(); 22 23 24 sub ret_vbox { 25 26 my $vbox = Gtk2::VBox->new(FALSE,5); 27 28 #create a scrolled window that will host the treeview 29 my $sw = Gtk2::ScrolledWindow->new (undef, undef); 30 $sw->set_shadow_type ('etched-out'); 31 $sw->set_policy ('automatic', 'automatic'); 32 #This is a method of the Gtk2::Widget class,it will force a minimum 33 #size on the widget. Handy to give intitial size to a 34 #Gtk2::ScrolledWindow class object 35 $sw->set_size_request (300, 300); 36 #method of Gtk2::Container 37 $sw->set_border_width(5); 38 39 #this is one of the provided base Gtk2::TreeModel classes. 40 my $tree_store = Gtk2::TreeStore->new(qw/Glib::String/); 41 42 #fill it with arbitry data 43 foreach (1..3) { 44 45 my $parent_nr = $_; 46 #the iter is a pointer in the treestore. We 47 #use to add data. 48 my $iter = $tree_store->append(undef); 49 $tree_store->set ($iter,0 => "Parent $parent_nr"); 50 51 foreach (1..3){ 52 #here we append child iters to the parent iter 53 #and add data to those chils iters. 54 my $iter_child = $tree_store->append($iter); 55 $tree_store->set ($iter_child,0 => "Child $_ of Parent $parent_nr"); 56 } 57 } 58 59 #this will create a treeview, specify $tree_store as its model 60 my $tree_view = Gtk2::TreeView->new($tree_store); 61 62 63 #create a Gtk2::TreeViewColumn to add to $tree_view 64 my $tree_column = Gtk2::TreeViewColumn->new(); 65 66 $tree_column->set_title ("Click to sort"); 67 68 #create a renderer that will be used to display info 69 #in the model 70 my $renderer = Gtk2::CellRendererText->new; 71 #add this renderer to $tree_column. This works like a Gtk2::Hbox 72 # so you can add more than one renderer to $tree_column 73 $tree_column->pack_start ($renderer, FALSE); 74 75 # set the cell "text" attribute to column 0 76 #- retrieve text from that column in treestore 77 # Thus, the "text" attribute's value will depend on the row's value 78 # of column 0 in the model($treestore), 79 # and this will be displayed by $renderer, 80 # which is a text renderer 81 $tree_column->add_attribute($renderer, text => 0); 82 83 #add $tree_column to the treeview 84 $tree_view->append_column ($tree_column); 85 86 # make it searchable 87 $tree_view->set_search_column(0); 88 89 # Allow sorting on the column 90 $tree_column->set_sort_column_id(0); 91 92 # Allow drag and drop reordering of rows 93 $tree_view->set_reorderable(TRUE); 94 95 $sw->add($tree_view); 96 97 $vbox->pack_start($sw,TRUE,TRUE,0); 98 $vbox->show_all(); 99 return $vbox; 100 }
In order to add something to the model, we use a two step process:
You have to add a row to the Gtk2::TreeStore
, using one of various available methods. The chosen method depends where you want the row to be added. This newly added row will be empty. The methods used to add it, will return a reference to a Gtk2::TreeIter
that you must use in the second step to append data to the row.
After a row is added to the Gtk2::TreeStore
, and you have a GGtk2::TreeIter
reference pointing to that row. Use Gtk2::TreeStore
's "set"
method to append data to this row.
The list of pairs must contain as many items as the number of columns in the |
Now you know the long way, you can look at the |
The Gtk2::TreeView
's "headers-clickable"
property really just sets the "clickable" property of the underlying Gtk2::TreeViewColumn
.
A Gtk2::TreeViewColumn
will not be sortable unless the tree model implements the TreeSortable interface and the Gtk2::TreeViewColumn
's set_sort_column_id()
method has been called with a valid column number.
When calling set_sort_column_id()
, the "headers-clickable"
property of the Gtk2::TreeView
is implicitly set to "TRUE" behind the scenes.
The "reorderable"
property of Gtk2::TreeView
enables the user to reorder the Gtk2::TreeView
model by dragging and dropping the Gtk2::TreeView
rows displayed.
The "rules-hint"
property of Gtk2::TreeView
hint to the theme engine to draw rows in alternating colors. This eases readability.