At certain points in your application, it makes sense to wait until something happens. For instance, if you create a ColorEditor window and want it to assign the color the user selects to a variable, you can use waitVariable to wait until the variable is set. For complete details, see Chapter 15, "Anatomy of the MainLoop".
To have a program wait until a variable's value is changed, call waitVariable:
$widget->waitVariable(\$var);
Processing will continue as soon as the value contained within $var is changed to something different. To wait until a $widget is visible, use waitVisibility:
$widget->waitVisibility;
To wait until a widget is destroyed, call waitWindow:
$widget->waitWindow;
When you call these methods, nothing will happen in your program until the requested event has taken place.
An alternative to waitWindow is OnDestroy, where you specify a callback. The widget methods are still available when you use OnDestroy:
$widget->OnDestroy(sub { ... });
There is a special method in Perl/Tk called fileevent, which watches and notifies you when a file is readable or writable. For complete details see Chapter 15, "Anatomy of the MainLoop", Chapter 19, "Interprocess Communicationwith Pipes and Sockets", and Chapter 22, "Perl/Tk and the Web".
Here is an example that shows how fileevent can be used (this code is meant to be executed on a Unix system because we use the Unix tail command):[31]
[31] Thanks to Phivu Nguyen for sharing this code.
use Tk; open (FH, "tail -f -n 25 text_file|") || die "Could not open file!\n"; my $mw = MainWindow->new; my $text = $mw->Scrolled("Text", -width => 80, -height => 25)->pack(-expand => 1); $mw->fileevent(FH, 'readable', [\&insert_text]); MainLoop; sub insert_text{ my $curline; if ($curline = <FH>) { $text->insert('end', $curline); $text->yview('moveto', 100); } else { $mw->fileevent(FH, 'readable', ""); } }
This short program sits around and waits until a file is readable and then inserts the newly read information into a Listbox. You can also use 'writable'.
$mw->fileevent(FH, 'writable', callback);
If you omit the callback portion, the callback will be returned. Replace the callback with an empty string ("") and the callback is removed.