strange behaviour with p_bar update
- From: Syed Imran <imran s4-technology com>
- To: Gtk-Perl-List <gtk-perl-list gnome org>
- Subject: strange behaviour with p_bar update
- Date: Mon, 26 Jul 2004 12:28:14 +1200
Hi all..
I've got a perl script that reads in the output from running another
program and displays it in a textview within a scrolled window.
There is also a fixed-time progress bar that runs for a certain period
of time whenever the external program is called. When I detect the
external program has finished or caused an error, I call the progress
bar update function with an argument to remove itself from being called
again and again. (i.e return FALSE)
It _does not_ work, the progress bar continues to get updated. I'm sure
there is a way to do what I want. Can somebody shed some light?
start-test.pl::
#!/usr/bin/perl -w
use Data::Dumper;
use FindBin;
use Glib 1.040, qw(TRUE FALSE);
use Gtk2 -init;
use IO::File;
# if( $> ) {
# die "Sorry only root must execute $FindBin::Script\n\n" unless (-r
$device && -w $device);
# }
# create the main window
my $window = Gtk2::Window->new;
$window->signal_connect(delete_event => sub{exit});
$window->set_resizable( FALSE );
$window->set_size_request( 400, 300 );
$window->set_title("FlashGTK ;)");
# add vbox to contain the SW and button
my $vbox = Gtk2::VBox->new;
$window->add($vbox);
# add a combobox with the device list
#my $model = Gtk2::ListStore->new( 'Glib::String' );
#foreach (qw!/dev/sda /dev/sdb /dev/sdc /dev/sdd!) {
# $model->set( $model->append, 0, $_ );
#}
#my $combo = Gtk2::ComboBox->new( $model );
my $combo = Gtk2::ComboBox->new_text;
$combo->append_text( '/dev/sda' );
$combo->append_text( '/dev/sdb' );
$combo->append_text( '/dev/sdc' );
$combo->append_text( '/dev/sdd' );
$combo->set_active( 0 );
$vbox->pack_start( $combo, FALSE, FALSE, 0 );
# SW container and textview inside it
my $scroller = Gtk2::ScrolledWindow->new;
$vbox->pack_start( $scroller, TRUE, TRUE, 0 );
my $textview = Gtk2::TextView->new;
my $buffer = $textview->get_buffer;
my $end_marker = $buffer->create_mark('end', $buffer->get_end_iter,
FALSE);
$buffer->signal_connect(insert_text => sub{
# $textview->scroll_to_mark($buffer->get_mark('end'), 0.0, TRUE, 0,
0.5);
$textview->scroll_mark_onscreen( $end_marker );
});
$scroller->add($textview);
# progress bar
my $pbar = Gtk2::ProgressBar->new();
$vbox->pack_start( $pbar, FALSE, FALSE, 0 );
# GO button
my $button = Gtk2::Button->new('go');
$button->signal_connect(clicked => \&button_handler);
$vbox->pack_start($button, FALSE, FALSE, 0);
# show window and start the gtk main loop
$window->show_all;
Gtk2->main;
exit;
sub button_handler()
{
$button->set_sensitive(FALSE);
Glib::Timeout->add( 120, \&pbar_update );
$pbar->set_text( "...flashing..." );
# Gtk2->main_iteration while Gtk2->events_pending;
my $buff = $textview->get_buffer;
$buff->insert($buff->get_end_iter, "Starting installation...\n");
my $fh = new IO::File;
my $pid = $fh->open( "-|" );
die "fork failed:: $!\n" unless defined $pid;
if( $pid == 0 )
{
# child
# open $chfh, "unbuffer ./instflash|";
open $chfh, "unbuffer false|";
while( !eof($chfh) )
{
my $data = <$chfh>;
if( defined $data )
{
print "Perl:: $data";
}
}
close( $chfh );
exit;
}
else
{
# parent
Glib::IO->add_watch( fileno $fh, [qw/in hup err/], \&watch_callback,
$fh );
}
}
sub pbar_update
{
my $arg = shift;
# print "\$arg==>$arg<==\n";
# return FALSE if defined( $arg );
my $newval = $pbar->get_fraction + 0.005;
$newval = 2 if defined( $arg );
print "\$newval ==> $newval\n";
if( $newval > 1.0 )
{
$button->set_sensitive( TRUE );
$pbar->set_fraction( 0 );
$pbar->set_text( " " );
return FALSE;
}
$pbar->set_fraction( $newval );
return TRUE;
}
sub watch_callback
{
my ($fd, $condition, $fh) = @_;
if( $condition >= 'in' )
{
my $data = <$fh>;
if( defined $data )
{
my $buffer = $textview->get_buffer;
$buffer->insert( $buffer->get_end_iter, $data );
}
}
if( $condition >= 'hup' or $condition >= 'err' )
{
pbar_update( 'stop' );
$fh->close;
$fh = undef;
}
if( $fh )
{
return TRUE;
}
else
{
return FALSE;
}
}
::end-test.pl
Currently I'm exec'ing /bin/false which returns unsuccessfully
immediately. hence i should see my progress bar stop as soon as it
starts. I can see the button being set to sensitive when the external
program finishes, just the progress bar doesn't stop.
For those who think using /bin/false is a bad idea, a simple script like
this will suffice::
#!/bin/bash
echo "blah blah"
sleep 5
/bin/false
# exit -2 <-- this'll work too
Regards,
Imran
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]