Problem
This is in response to vlada's post titled Block/revert combobox selection.
In How to revert combobox selection - Part 1 - using block?, we used GObject::block() to temporarily block the signal while reverting back the combo options to its previous value.
In this part 2, I'll show you the second method that will achieve the same effect as shown below.
Solution
- If the user decides not to change the option, instead of blocking the signal as we've done in method 1, we let the signal pass through, but 'gobble' it up with GObject::emit_stop_by_name()
- Note that we need a flag to know when we should gobble up the signal. Hence the global variable
$is_revert
.
Important Note: This only works for PHP-GTK2 compliled with gtk+ v2.10 and above. If you are using an older version, for linux, you may follow the step-by-step instructions to recompile php-gtk2 with gtk+ v2.10. For windows, please refer to How to install php gtk2 on windows? You may also want to take a look here to see some of the new exciting PHP-GTK2 Functionalities.
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 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 105 106 107 108 109 110 111 112 113 114 | <?php $window = new GtkWindow(); $window->set_title($argv[0]); $window->connect_simple('destroy', array( 'Gtk', 'main_quit')); $window->set_size_request(400,150); $window->add($vbox = new GtkVBox()); // display title $title = new GtkLabel(" Revert combobox selection\n". "Part 2 - using emit_stop_by_name()"); $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 $list = array('item 1', 'item 2', 'item 3', 'item 4'); $vbox->pack_start($hbox=new GtkHBox(), 0, 0); $hbox->pack_start(new GtkLabel('Select: '), 0, 0); // Create a combobox $combobox = new GtkComboBox(); // Create a model if (defined("GObject::TYPE_STRING")) { $model = new GtkListStore(GObject::TYPE_STRING); } else { $model = new GtkListStore(Gtk::TYPE_STRING); } // Set up the combobox $combobox->set_model($model); $cellRenderer = new GtkCellRendererText(); $combobox->pack_start($cellRenderer); $combobox->set_attributes($cellRenderer, 'text', 0); $combobox->connect('changed', 'on_change'); $hbox->pack_start($combobox, 0, 0); $prev_index = -1; $is_revert = 0; // note 1 // Stuff the choices in the model foreach($list as $choice) { $model->append(array($choice)); } $window->show_all(); Gtk::main(); function on_change($combobox) { global $is_revert; if ($is_revert) { // note 2 $combobox->emit_stop_by_name ('changed'); // note 3 $is_revert = 0; return true; } $model = $combobox->get_model(); $selection = $combobox->get_active_text(); global $prev_index, $prev_selection; $selected_index = $combobox->get_active(); $response = yes_no_dialog("Previous selection: $prev_selection\n". "New selection: $selection\n". "Are you sure you want to make the change?"); echo "You have selected: $selection (index=$selected_index)! ". "(response = $response)\n"; switch($response) { case Gtk::RESPONSE_YES: echo "yes, change the option\n"; $prev_index = $selected_index; $prev_selection = $selection; break; case Gtk::RESPONSE_NO: // note 4 echo "no, revert to the original value\n"; $is_revert = 1; // note 4 $combobox->set_active($prev_index); break; } } function yes_no_dialog($msg) { $dialog = new GtkDialog(); $dialog->set_title('Yes/No Dialog'); $label = new GtkLabel($msg); $dialog->vbox->pack_start($label); $dialog->add_buttons(array( Gtk::STOCK_YES, Gtk::RESPONSE_YES, Gtk::STOCK_NO, Gtk::RESPONSE_NO )); $dialog->show_all(); $response_id = $dialog->run(); $dialog->destroy(); return $response_id; global $response; return $response; switch($response_id) { case Gtk::RESPONSE_YES: $response->set_text("$response_id (Yes)"); break; case Gtk::RESPONSE_NO: $response->set_text("$response_id (No)"); break; } } ?> |
Output
As shown above.Explanation
We make use of the code from How to revert combobox selection - Part 1 - using block?
What's new here:
- We used a global variable
$is_revert
to keep track of whether we are reverting the combobox option. - Check if we are reverting the option.
- If yes, we use
emit_stop_by_name
to gobble up the 'changed' signal. - If the user selects No, we set the global variable
$is_revert
to 1.
Read more...