Gtk2::MessageDialog
and interesting parts of our program. Gtk2::MessageDialog
is a subclass of Gtk2::Dialog
. Gtk2::Dialog
in turn is a subclass of Gtk2::Window
.
Gtk2::MessageDialog
gets created by either the new
or new_with_markup
methods. The latter allows your message's text to be formatted using Pango markup. It is quite safe to use the latter, even if you display normal text without Pango markup, just ensure the text string does not contain Pango markup characters.(typically the "<" and ">" characters)
Since the |
To create a Gtk2::MessageDialog
, you use the following:
widget = Gtk2::MessageDialog->new ($parent, $flags, $type, $buttons, $format, ...) * $parent (Gtk2::Window or undef) * $flags (Gtk2::DialogFlags) * $type (Gtk2::MessageType) * $buttons (Gtk2::ButtonsType) * $format (scalar) * ... (list)
$parent
can be undef, but it is good practice to use a valid $parent whenever possible, especially for Gtk2::MessageDialog
s. This will cause the Gtk2::MessageDialog
to display on top of the parent window, instead of the middle if the screen, when $parent
is undef
.
If you don't set $parent
, it's possible for the message dialog to get lost behind the main window, which can be confusing and infuriating to the user when the dialog is modal (because the app is now inexplicably not responding).
The top button calls the show_message_dialog
sub with $parent
undefined. When you move the main window around, each Gtk2::MessageDialog
that gets shown, will pop up in the center of the screen, and NOT on top of the main window. With the other buttons, we use the main window as $parent
. This will cause each Gtk2::MessageDialog
to display on top of the main window.
There are different types of messages, the type of message will be indicated by the Gtk2::Dialog
's icon, as well as its title.
To obtain a list of message types (Gtk2::MessageType), we use a little-known feature in Glib
that is also used in the Gtk2-Perl
project for the documentation generator:
#we ask Glib to give a list of values for Gtk2::MessageType. #Each value of the list is a hash with keys "name" and "nick", #we then use the value of "nick" to specify the type to show. foreach my $m_type (Glib::Type->list_values ('Gtk2::MessageType')){So we ask the bindings to list all the values for a particular enum type. That way, you don't have to update your program's code when a future version of Gtk+ adds a value to the enumeration, and you don't have to worry about misspelling one.
See the Glib::Type
manpage for more info.
To get the nick
, we use $m_type->{'nick'}
from the returned hash. The message that gets displayed will also show how it was created.
This brings us to the buttons to display on the message. Taking a look at the code of the bottom button, we extract a list of all the possible button types, and loop through them, showing a message containing each button type.
#we ask Glib to give a list of values for Gtk2::ButtonsType. #Each value of the list is a hash with keys "name" and "nick", #we then use the value of "nick" to specify the button to show. foreach my $b_type (Glib::Type->list_values ('Gtk2::ButtonsType')){
The Gtk2::MessageDialog
has a run
method that gets called to show it. This will put, depending of the type of message (modal or not) either the whole program, or just the message in a loop, waiting for user input.
The run
method returns a string value, indicating how the loop was terminated. In our program, this value is displayed in the calling window's label.
my $retval = $dialog->run;
You can drag the calling window to the side of the screen to get a clearer view. |
yes
or no
if your message contained the yes-no
button type for instance.
This does not have anything to do with Gtk2::MessageDialog
classes. It is part of the program's main loop.
All Gtk2-Perl
programs use the Glib::MainLoop
implicitly when calling the Gtk2
's main
method. The Glib::MainLoop
loop has three methods that may be of interest. The callbacks for Glib::Timeout
, Glib::Timeout
, and Glib::IO
all expect a boolean return value. TRUE means "yes, I want to run again," FALSE means "no, please uninstall me".
Omitting this return value is a very common cause of application bugs. |
Glib::Timeout
. This is the one we used. We specify what should be done, and how often. The time is specified in milliseconds.
#create a flasher for the label, we will show or hide it every 1 second
my $flash = 1;
Glib::Timeout
->add (1000,sub{ flash_label() });
Glib::Idle
. This is most handy for "single-shot" deferred actions, like this:
# schedule do_something() to run when the main loop goes idle. Glib::Idle->add (sub { do_something (); FALSE; # don't run again });This is what happens when you call "$widget->queue_redraw()", for example. You should use
Glib::Timeout
in other situations, when possible .
Glib::IO
. This is used to get data from a filehandle. We will discuss it in depth later.
show
and hide
methods of the class.
sub flash_label { #label flasher ($flash)&&($label_feedback->hide()); ($flash)||($label_feedback->show()); $flash = !($flash); return TRUE; }