Glib::MainLoop
Every GUI program has to enter a loop that will enable it to handle user actions as well as external input. To enter this loop in Gtk2-Perl
we use Gtk2->main;
.
In previous lessons we used the Glib::Timeout
method to execute a sub on a frequency specified as an argument. This lesson will look at the more complex Glib::IO
method. We will also look at the preferred Gtk2::Helper
class, which servers as a Glib::IO
wrapper. They will typically be used to read from files or network sockets.
When exposed to something new, its always good to take baby steps. We will start of with a program that is so much less it does not even feature a GUI!
This program will open a filehandle and print any new text in the file to standard out. This may sound pretty boring, but adding a GUI to this basic concept, we can create a log file reader , and if we feel really adventures, create a chat program, using sockets.
The program can be found here: 'Mini Glib::IO
Demo'
1 #!/usr/bin/perl -w 2 use strict; 3 use Gtk2 -init; 4 use IO::File; 5 use Glib qw(TRUE FALSE); 6 7 my $fh = new IO::File; 8 my $pid = $fh->open ("./test.log"); 9 10 Glib::IO->add_watch (fileno $fh, [qw/in/], 11 \&watch_callback, $fh); 12 13 Gtk2->main; 14 15 sub watch_callback { 16 17 my ($fd, $condition, $fh) = @_; 18 my @lines = $fh->getlines; 19 print @lines; 20 #always return TRUE to continue the callback 21 return TRUE; 22 }
To add a watch to a filehandle (filehandles include network sockets, files and feedback from commands), do the following:
Select the Perl IO module you require, in this sample, we use IO::File
.
Initialize and open the filehandle. This is how we did it:
my $fh = new IO::File; my $pid = $fh->open ("./test.log");
Add a watch on this filehandle to the mainloop:
Glib::IO->add_watch (fileno $fh, [qw/in/], \&watch_callback, $fh);
Remember to use the There is a last optional argument not used here, called |
Variations on the callback sub:
This sample only reads new values from the file, but should the whole file change, and you need to re-read it, use the $fh->seek ( 0, 0 );
method before using the getlines
method. This will reposition the buffer pointer to the start of the file. (This method is part of IO::Seekable, which is available to IO::File). Imagine you have a file with only one line, and this line keeps changing, then you will use this method.
If you want to see the program do something, echo text into the file that was opened for reading.
# echo "Whatever U want, Whatever U need" >> ./test.logThis will be caught by the
getlines
method (This method is part of IO::Handle, and also available to IO::File). It should to be used in a list context, and NOT in a scalar context, thats why we have the "@lines".