045. How to use GtkCellRendererToggle - Part 2 - process selection?

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:

How to use GtkCellRendererToggle - Part 2 - process selection?


Solution


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

  1. Note that we need the pointer to $model for use later.
  2. 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.
  3. 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.
  4. Get the iter from path.
  5. Get the status of the checkbox.
  6. Check if the checkbox is selected.

Related Articles

Add comment


Security code
Refresh