Problem updating DrawingArea

Hi all,

I'm updating some text on a drawing area using draw_string and a
timeout. This works fine except the drawing area flickers every few
seconds during the update. I believe this is caused by redrawing the
rectangle (draw_rectangle) every time my timeout is called. How can I
avoid this flickering, or more specifically, how can avoid having to
redraw the drawing area while updating the text on it.

Below is an example program that displays this problem.

#!/usr/bin/perl -w

use Gtk;
use strict;


my $false = 0;
my $true = 1;

my ( $win, $vbox, $frame, $drawing_area, $timeout );

$win = new Gtk::Window( '-toplevel' );
$win->set_title( 'DrawingArea Example' );
$win->signal_connect( 'destroy', sub {Gtk->exit( 0 )} );

$vbox = new Gtk::VBox( $false, 0 );
$win->add( $vbox );

$frame = new Gtk::Frame();
$frame->set_shadow_type( 'in' );

$drawing_area = new Gtk::DrawingArea();
$drawing_area->size( 640, 85 );
$drawing_area->signal_connect( 'configure_event', \&draw_shapes );
$drawing_area->signal_connect( 'expose_event', \&draw_text );

$frame->add( $drawing_area );
$vbox->pack_start( $frame, $false, $false, 0 );


$timeout = Gtk->timeout_add( 250, \&add_text, $drawing_area->window );


Subs                                                        #
sub add_text
   my ($drawable, $event) = @_;
   my ($width, $height, $font, $black_gc, 
       $white_gc, $cur_time, $uptime);

   $width = $drawing_area->allocation->[2];
   $height = $drawing_area->allocation->[3];

   $font =
   $black_gc = $drawing_area->style->black_gc;
   $white_gc = $drawing_area->style->white_gc;

   $uptime = `uptime`; chomp($uptime);
   $cur_time = "The time is now ".`date`; chomp($cur_time);

   $drawable->draw_rectangle( $black_gc, $true, 0, 0, $width, $height );
   $drawable->draw_string( $font, $white_gc, 5, 25, $uptime );
   $drawable->draw_string( $font, $white_gc, 15, 55, $cur_time);

   return $true;

sub draw_text
   my ($drawing_area, $event) = @_;
   my $drawable = $drawing_area->window;

   &add_text($drawable, $event);

   return $false;

sub draw_shapes
   my ($drawing_area, $event) = @_;
   my ($drawable, $width, $height, $black_gc);

   $drawable = $drawing_area->window;
   $width = $drawing_area->allocation->[2];
   $height = $drawing_area->allocation->[3];
   $black_gc = $drawing_area->style->black_gc;

   $drawable->draw_rectangle( $black_gc, $true, 0, 0, $width, $height );

   return $true;

Granted, it can be very hard to notice the flickering in this example,
but if you watch carefully, you should be able to see it every couple of
seconds. The actual program I'm writing that uses this routine does more
complex operations than just calling 'date' and 'uptime' so the
flickering is more pronounced.

I think the correct method is to use a backing pixmap but I don't fully
understand how to implement that.

Any pointers would be much appreciated.


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