026. How to change buttons on the fly based on pulldown menu selections?

Problem

You want to change the buttons on the fly depending on the selection from a pulldown menu as shown below:

How to change buttons on the fly based on pulldown menu selections?

 

For example, when you select "This is item 2", the buttons will change to:


Warning: Unterminated comment starting line 1 in /var/www/kksou.com/public_html/php-gtk2/plugins/content/DirectPHP/DirectPHP.php(56) : eval()'d code on line 1
" />

*/ ?>

Solution

  • Create pulldown menu with GtkComboBox
  • Create all the buttons first and hide them.
  • Depending on the selection, set the labels of the buttons, and show or hide the buttons accordingly.

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   
96   
97   
98   
99   
100   
101   
102   
103   
104   
<?php
$window = new GtkWindow();
$window->connect_simple('destroy', array( 'Gtk', 'main_quit'));
$window->set_size_request(400,200);
$window->add($vbox = new GtkVBox());

// display title
$title = new GtkLabel("Changing buttons on-the-fly based on 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, 60);
$vbox->pack_start($title, 0, 0);

// the selection
$options = array(
    'item1' => 'This is item 1',
    'item2' => 'This is item 2',
    'item3' => 'This is item 3',
    'item4' => 'This is item 4');

// the buttons
$buttons = array( // note 1
'item1' => array('File', '', 'Exit'),
'item2' => array('button2-1', 'button2-2', 'button2-3'),
'item3' => array('', 'button3-2', 'Exit'),
'item4' => array('', '', 'Exit')
);
$button_ptr = array();
$button_handler = array();

// setup the buttons
$vbox->pack_start($hbox=new GtkHBox(), 0, 0); // creates a hbox container
for ($i=0; $i<3; ++$i) { // 3 because we have 3 buttons
    $hbox2 = new GtkHBox(); // forms the base of button
    $button = new GtkButton(''); // creates an empty button
    $button->set_size_request(100, 32); // set the size of button
    $button_ptr[$i] = $button; // store the pointer to button
    $hbox2->set_size_request(120, 40); // pack the button inside the base
    $hbox2->pack_start($button, 0, 1); // to fix the position of the 3 buttons
    $hbox->pack_start($hbox2, 0, 0); // place the buttons on the same row
}

$vbox->pack_start(new GtkLabel(''), 0, 0); // give a slight gap

// setup the pulldown menu
$vbox->pack_start($hbox=new GtkHBox(), 0, 0); // creates a hbox container
$hbox->pack_start(new GtkLabel('Select: '), 0, 0); // to hold label and combobox
$combobox = new GtkComboBox(); // create the combobox

if (defined("GObject::TYPE_STRING")) {
    $model = new GtkListStore(GObject::TYPE_STRING); // create the model
} else {
    $model = new GtkListStore(Gtk::TYPE_STRING); // create the model
}
$combobox->set_model($model); // binds the model to combobox
$cellRenderer = new GtkCellRendererText(); // setup cellrenderer
$combobox->pack_start($cellRenderer); // set up first column
$combobox->set_attributes($cellRenderer, 'text', 0); // value map to $model[0]
$combobox->connect('changed', 'on_selection_change', $options, $buttons); // set up event handler
foreach($options as $choice) { $model->append(array($choice)); } // pupulates data
$hbox->pack_start($combobox, 0, 0); // show it besides the label "Select:"

function on_selection_change($combobox, $options, $buttons) {
    global $button_ptr, $button_handler;
    $model = $combobox->get_model(); // get the model
    $selected_value = $model->get_value($combobox->get_active_iter(), 0); // get the selected value
    $key = array_search($selected_value, $options); // get the key
    echo "You have selected: $selected_value (key=$key)!\n";

    for ($i=0; $i<3; ++$i) {
        $button_value = $buttons[$key][$i];
        if ($button_value == '') {
            // hide the buttons if button value is empty
            $button_ptr[$i]->hide();
        } else {
            $button_ptr[$i]->child->set_text($button_value);
            echo "button_value = $button_value\n";
            $button_ptr[$i]->show();
            // release any previous event handler first
            if (isset($button_handler[$i])) {
                $button_ptr[$i]->disconnect($button_handler[$i]); // note 3
            }
            // setup the event handler for button click
            $button_handler[$i] = $button_ptr[$i]->connect
            ('button-press-event', 'on_button', $key, $i); // note 2
        }
    }
}

// the function that is called when user clicks the button
function on_button($button, $event, $key, $button_index) { // note 2
    $button_value = $button->child->get_text();
    echo "You have clicked: $button_value ($key) ($button_index)!\n";
}

$window->show_all();

// hide the buttons first
for ($i=0; $i<3; ++$i) {
    $button_ptr[$i]->hide();
}

Gtk::main();
?>

Output

As shown above.
 

Explanation

Please refer to How to setup and process GtkComboBox? which explains in more detail how to set up a combobox.

  1. The array $buttons holds the values of the buttons for each selection. You can hide a button by setting it to ''.
  2. With php-gtk, you can handle the button clicks of all possible combinations of buttons with just one simple event handler. You just need to pass the right variables along with the events.
  3. Remember to disconnect all unused button-click events! Try leaving this out, and you will understand why you need to do this.

Related Articles

Add comment


Security code
Refresh