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::TreeModels 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::TreeViewColumns 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::TreeViewColumns 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::CellRenderers 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.