Re: $button->modify_bg() delay?

John Ello said:
Hi, I'm writing a program in Gtk2-perl where I'd like to change the
background color of a button several times if a user hits the wrong
button. It seems that ->modify_bg() doesn't take effect until the
called subroutine finishes though. Is there a way around this?  Below
is a test program where the button is changed to green, then red. I
only ever see the red.

Most things in gtk actually just enqueue work that gets performed in an idle
at some later time, mostly to reduce the number of required round trips with
the the X server.  Sounds like you're seeing just that.

Realistically, since flashing the color visibily requires the color to stay up
long enough for the user to see it, and people need a reasonable slice of a
second to see something, you'll want to do this with timeouts.


use Gtk2 -init;

my $button = new Gtk2::Button 'click me';
my $label = new Gtk2::Label 'WOO!';
my $ebox = new Gtk2::EventBox;
my $window = new Gtk2::Window;
my $box = new Gtk2::VBox;
$window->add ($box);
$ebox->add ($label);
$box->add ($ebox);
$box->add ($button);

$window->signal_connect (destroy => sub {Gtk2->main_quit});
$button->signal_connect (clicked => sub {
        flashy_thing ($ebox);


sub flashy_thing {
        my $widget = shift;

        # get a copy of the unmodified modifier style, so we can reset.
        my $plainstyle = $widget->get_modifier_style->copy;
        # modify the style that's already in there...
        $widget->modify_bg ('normal', Gtk2::Gdk::Color->new (65535, 0, 0));
        # and then get a reference to it for later.
        my $onstyle = $widget->get_modifier_style;

        my $n_flashes = 3;
        my $wax = 'on';
        Glib::Timeout->add (75, sub {
                if ($wax eq 'on') {
                        $widget->modify_style ($plainstyle);
                        $wax = 'off';
                } else {
                        $widget->modify_style ($onstyle);
                        $wax = 'on';
                # when n_flashes reaches 0, the timeout uninstalls itself.
                return $n_flashes;

    $button->modify_bg( 'normal', $green );
    $button->modify_bg( 'active', $green );
    $button->modify_bg( 'prelight', $green );
    sleep 5;

this kind of sleep actually pauses everything, causing the main loop not to
run.  your app will be completely unresponsive during this time.

    $button->modify_bg( 'normal', $red );
    $button->modify_bg( 'active', $red );
    $button->modify_bg( 'prelight', $red );

and then you changed it again, before gtk+ got a chance to apply the previous

muppet <scott at asofyet dot org>

[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]