034. How to use GtkCellRendererCombo - Part 1 - setup?

Problem

You would like to add a combobox (or pulldown menu) inside a treeview as shown below:

How to use GtkCellRendererCombo - Part 1 - setup?


Solution

  • Pulldown menus can be displayed inside a GtkTreeView with GtkCellrenderercombo.
  • The values to be displayed in the combo box are specified using a GtkListstore.

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   
87   
88   
89   
90   
91   
92   
<?php
$window = new GtkWindow();
$window->set_size_request(400, 200);
$window->connect_simple('destroy', array('Gtk','main_quit'));
$window->add($vbox = new GtkVBox());

// display title
$title = new GtkLabel("Using GtkCellRendererCombo - Part 1 (Setup)");
$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);

// 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));

display_table($vbox, $data);

$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_STRING, GObject::TYPE_STRING,
                    GObject::TYPE_LONG, GObject::TYPE_DOUBLE, GObject::TYPE_STRING);
    } else {
        $model = new GtkListStore(Gtk::TYPE_STRING, Gtk::TYPE_STRING,
                    Gtk::TYPE_LONG, Gtk::TYPE_DOUBLE, Gtk::TYPE_STRING);
    }
    $field_header = array('Row #', 'Description', 'Qty', 'Price');

    // Creates the view to display the list store
    $view = new GtkTreeView($model);
    $scrolled_win->add($view);

    // Creates columns
    for ($col=0; $col<count($field_header); ++$col) {
        $cell_renderer = new GtkCellRendererText();
        $column = new GtkTreeViewColumn($field_header[$col],
            $cell_renderer, 'text', $col);
        $view->append_column($column);
    }

    // Set up the combobox
    $cell_renderer = new GtkCellRendererCombo(); // note 1
    if (defined("GObject::TYPE_STRING")) {
        $category = new GtkListStore(GObject::TYPE_STRING); // note 2
    } else {
        $category = new GtkListStore(Gtk::TYPE_STRING); // note 2
    }
    $list = array('grp 1', 'grp 2', 'grp 3', 'grp 4');
    foreach($list as $choice) {
        $category->append(array($choice)); //n4 note3
    }
    $cell_renderer->set_property('model', $category); // note 4
    $cell_renderer->set_property('text-column', 0); // note 5
    $cell_renderer->set_property('editable', true); // note 6
    $cell_renderer->set_property('has-entry', true); // note 7

    $column = new GtkTreeViewColumn('Category', $cell_renderer, 'text', 4);
    $view->append_column($column);

    // pupulates the data
    for ($row=0; $row<count($data); ++$row) {
        $values = array();
        for ($col=0; $col<count($data[$row]); ++$col) {
            $values[] = $data[$row][$col];
        }
        $values[] = ''; // set category to be '' first

        $model->append($values); // stuff the values into the data model
    }
}

?>

Output

As shown above.

 

Explanation

  1. Create a new combobox renderer.
  2. Create a liststore to store the options of the combobox. Note: Please refer to the comments from Andre Colomb: "If you change the column type of the list store to Gtk::TYPE_LONG and fill it with integers, the application crashes as soon as one selects a value from the list." This might be a php-gtk bug. Till they fix it, just use Gtk::TYPE_STRING for the model of the combobox.
  3. Populate the combobox.
  4. It is here that we bind the data model of the combo box to the renderer with: GtkCellrenderercombo::model().
  5. '0' refers to the 1st col in $category
  6. Allow user to change value
  7. When you set GtkCellrenderercombo::has-entry() to true, you allow users to specify values other than those in the combo box. Set it to false if you only want users to select from the list.

Note

Note that here we have only set up the combo box. You can now see the combo box and selects the value. However the moment you select another row, the value disappears. This is because the value is not being stored in the data model associated with the tree view.

In Part 2, we will show you how to process user selection from the combo box.

Related Links

Add comment


Security code
Refresh