Problem
We have set up checkboxes for user to select rows in Part 1. Now you would like to perform some actions based on user selections in a GtkTreeView as shown below:
Solution
- Get the total number of rows in the model with GtkTreemodel::iter_n_children().
- Get the iter for each row using GtkTreemodel::get_iter().
- With the iter, we can now get the value of each column with GtkTreemodel::get_value().
Sample Code
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 118 119 120 121 122 | <?php $window = new GtkWindow(); $window->set_size_request(400, 230); $window->connect_simple('destroy', array('Gtk','main_quit')); $window->add($vbox = new GtkVBox()); // display title $title = new GtkLabel("Using GtkCellRendererToggle - Part 2\n". " (Process Selection)"); $title->modify_font(new PangoFontDescription("Times New Roman Italic 10")); $title->modify_fg(Gtk::STATE_NORMAL, GdkColor::parse("#0000ff")); $title->set_size_request(-1, 40); $vbox->pack_start($title, 0, 0); $vbox->pack_start(new GtkLabel(), 0, 0); $vbox->pack_start($hbox = new GtkHBox, 0, 0); $button = new GtkButton('Process Order'); $hbox->pack_start(new GtkLabel('Select the items and press '), 0, 0); $hbox->pack_start($button, 0, 0); // the 2D table $data = array( array('row0', 'item 1', 2, 3.1), array('row1', 'item 4', 5, 6.21), array('row2', 'item 7', 8, 9.36), array('row3', 'item 10', 11, 12.4), array('row4', 'item 21', 14, 15.5), array('row5', 'item 36', 17, 18.6), array('row6', 'item 42', 20, 21.73)); $model = display_table($vbox, $data); // note 1 $button->connect('clicked', 'on_clicked', $model); // note 2 $window->show_all(); Gtk::main(); function display_table($vbox, $data) { // Set up a scroll window $scrolled_win = new GtkScrolledWindow(); $scrolled_win->set_policy( Gtk::POLICY_AUTOMATIC, Gtk::POLICY_AUTOMATIC); $vbox->pack_start($scrolled_win); // Creates the list store if (defined("GObject::TYPE_STRING")) { $model = new GtkListStore(GObject::TYPE_BOOLEAN, GObject::TYPE_STRING, GObject::TYPE_STRING, GObject::TYPE_LONG, GObject::TYPE_DOUBLE); } else { $model = new GtkListStore(Gtk::TYPE_BOOLEAN, Gtk::TYPE_STRING, Gtk::TYPE_STRING, Gtk::TYPE_LONG, Gtk::TYPE_DOUBLE); } $field_header = array('Row #', 'Description', 'Qty', 'Price'); // Creates the view to display the list store $view = new GtkTreeView($model); $scrolled_win->add($view); // Creates the selection column $cell_renderer = new GtkCellRendererToggle(); $cell_renderer->set_property('activatable', true); $column = new GtkTreeViewColumn('Select', $cell_renderer, 'active', 0); $column->set_cell_data_func($cell_renderer, "format_col"); $cell_renderer->connect('toggled', 'on_toggle', $model); $view->append_column($column); // Creates the rest of the column for ($col=0; $col<count($field_header); ++$col) { $cell_renderer = new GtkCellRendererText(); $column = new GtkTreeViewColumn($field_header[$col], $cell_renderer, 'text', $col+1); $column->set_cell_data_func($cell_renderer, "format_col"); $view->append_column($column); } // pupulates the data for ($row=0; $row<count($data); ++$row) { $values = array(0); for ($col=0; $col<count($data[$row]); ++$col) { $values[] = $data[$row][$col]; } $model->append($values); } return $model; } // toggle the selection box function on_toggle($renderer, $row, $model) { $iter = $model->get_iter($row); // get the iter $model->set($iter, 0, !$model->get_value($iter, 0)); } // process user selection function on_clicked($button, $model) { $num_rows = $model->iter_n_children(NULL); // note 3 for ($i=0; $i<$num_rows; ++$i) { $iter = $model->get_iter($i); // note 4 $selected = $model->get_value($iter, 0); // note 5 if ($selected) { // note 6 $row_id = $model->get_value($iter, 1); $row_desc = $model->get_value($iter, 2); $qty = $model->get_value($iter, 3); $price = $model->get_value($iter, 4); echo "You have selected: $row_id ($row_desc) qty=$qty (price=$price)\n"; // your action here } } } // display alternate row color function format_col($column, $cell, $model, $iter) { $path = $model->get_path($iter); $row_num = $path[0]; $row_color = ($row_num%2==1) ? '#dddddd' : '#ffffff'; $cell->set_property('cell-background', $row_color); } ?> |
Output
As shown above.
Explanation
- Note that we need the pointer to
$model
for use later. - Set up the event handler to respond to user click on the "Process Order" button. Note that we need to pass
$model
along for use later. - GtkTreemodel::iter_n_children() allows us to get the total number of rows in the treeview. Since ours is a list (as oppose to a tree), there is only one level. For one level list, we just pass in
NULL
which implies the root level. - Get the iter from path.
- Get the status of the checkbox.
- Check if the checkbox is selected.
Read more...