PHP-GTK2 Newsletter

PHP-GTK2 Tips & Techniques
FREE Newsletter
by kksou



Sample Code 360: How to prevent concurrent button clicks - Part 1 - using block?
Written by kksou   
Thursday, 08 November 2007
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.

How to prevent concurrent button clicks - Part 1 - using block?


Solution

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;
    }
}

?>
Explanation

The above example make use of the code from How to process concurrent button clicks?.

What's new here:

  1. Block any further button clicks while the processing is in progress.
  2. Processing done. Let's start to allow new button clicks.

Related Links

User reviews

There are no user reviews yet.

Note: You have to be a registered member to leave a comment. Free registration here.

 
< Prev   Next >

Blog - Forum - Privacy Policy - Contact Us
Copyright © 2006-2009. kksou.com. All Rights Reserved