Problem
This is in response to Benjamin Smith's post titled Preventing concurrent processing.
Suppose you have set up two buttons as shown below.
In this article, I will show you the first method in preventing concurrent clicks on the buttons. You will find that if you click on the first button1, until button1 finishes its processing, clicking on button1 or button2 will not have any effect.
Solution
- To block a signal, we use GObject::block().
- To unblock a signal, we use GObject::unblock().
Note: Would strongly encourage you to take a look at the article How to process concurrent button clicks? if you haven't. You will understand more about the problem and the solutions.
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 44 45 46 47 48 49 50 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 | <?php $window = new GtkWindow(); $window->set_size_request(400, 175); $window->connect_simple('destroy', array('Gtk','main_quit')); $window->add($vbox = new GtkVBox()); // display title $title = new GtkLabel("Prevent concurrent button clicks\n". " Part 1 - using block()"); $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); $vbox->pack_start(new GtkLabel(), 0); $vbox->pack_start($hbox = new GtkHBox(), 0); $hbox->pack_start($vbox1 = new GtkVBox(), 0); $hbox->pack_start(new GtkVBox()); $hbox->pack_start($vbox2 = new GtkVBox(), 0); $vbox1->pack_start($button1 = new GtkButton('Button 1'), 0); $vbox1->pack_start($status11 = new GtkLabel(), 0); $vbox1->pack_start($status12 = new GtkLabel(), 0); $vbox1->pack_start($progress1 = new GtkProgressBar(), 0); $progress1->set_orientation(Gtk::PROGRESS_LEFT_TO_RIGHT); $handler[1] = $button1->connect('clicked', 'on_button', 1, $progress1, $status11, $status12); $num_clicks[1] = 0; $vbox2->pack_start($button2 = new GtkButton('Button 2'), 0); $vbox2->pack_start($status21 = new GtkLabel(), 0); $vbox2->pack_start($status22 = new GtkLabel(), 0); $vbox2->pack_start($progress2 = new GtkProgressBar(), 0); $progress2->set_orientation(Gtk::PROGRESS_LEFT_TO_RIGHT); $handler[2] = $button2->connect('clicked', 'on_button', 2, $progress2, $status21, $status22); $num_clicks[2] = 0; $window->show_all(); Gtk::main(); function on_button($button, $id, $progress, $status1, $status2) { global $handler, $button1, $button2; $button1->block($handler[1]); // note 1 $button2->block($handler[2]); // note 1 global $num_clicks, $progress_count; ++$num_clicks[$id]; $progress_count[$id][$num_clicks[$id]] = 0; $status1->set_text("Total number of clicks ($id): {$num_clicks[$id]}"); Gtk::idle_add('update_progressbar', $progress, $id, $num_clicks[$id], $status1, $status2); } function update_progressbar($progress, $id, $num_clicks, $status1, $status2) { $max = 1000; global $progress_count; ++$progress_count[$id][$num_clicks]; $count = $progress_count[$id][$num_clicks]; $percent_complete = $count/$max; $percent_complete2 = number_format($count/$max*100, 0); $progress->set_fraction($percent_complete); $progress->set_text($percent_complete2.'% Complete'); while (Gtk::events_pending()) {Gtk::main_iteration();} $status2->set_text("Now running click #$num_clicks"); if ($count < $max) { // task completed? return true; // not yet! } else { global $num_clicks; --$num_clicks[$id]; $status1->set_text("Total number of clicks: {$num_clicks[$id]}"); while (Gtk::events_pending()) {Gtk::main_iteration();} global $handler, $button1, $button2; $button1->unblock($handler[1]); // note 2 $button2->unblock($handler[2]); // note 2 return false; } } ?> |
Output
As shown above.Explanation
The above example make use of the code from How to process concurrent button clicks?.
What's new here:
- Block any further button clicks while the processing is in progress.
- Processing done. Let's start to allow new button clicks.
Related Links
- How to prevent concurrent button clicks - Part 2 - using set sensitive?
- How to prevent concurrent button clicks - Part 3 - using emit stop by name?
- How to prevent concurrent button clicks - Part 4 - support for queuing of button clicks?
- How to process concurrent button clicks?
- How to display progress bar while processing long task - Part 1?
Read more...