Gtk2::Button This lesson will look at the Gtk2::Button class. We will also use one of Gtk2::Button's subclasses called Gtk2::CheckButton. This in itself is a subclass of Gtk2::ToggleButton. So we have Gtk2::Button->Gtk2::ToggleButton->Gtk2::CheckButton in the class hierarchy.
This lesson will also introduce three new widget classes. They are Gtk2::Frame, Gtk2::ScrolledWindow and Gtk2::Image.
Last but not least, we will introduce the reader to the Gtk2::Stock items and the cursor (Gtk2::Gdk::Cursor).
Table 7-1. Gtk2 object classes used
Gtk2 Class Name |
|---|
Gtk2::Window |
Gtk2::VBox |
Gtk2::Button |
Gtk2::CheckButton |
Gtk2::Frame |
Gtk2::Image |
Gtk2::ScrolledWindow |
Gtk2::Gdk::Cursor |
Gtk2::Stock |
Gtk2::Button
The Gtk2::Button is a subclass of Gtk2::Bin, so we can add only one child widget to it. By default, the text specified with the Gtk2::Button ->new() method, will be added as a Gtk2::Label class object. The newer versions of Gtk2-Perl allows you to add a Gtk2::Image class object with the Gtk2::Button ->set_image method.
This is a nice feature to quickly create a picture button, or a button with a picture and a label. This saves time, as previously you first had to create a Gtk2::HBox class object, then add a Gtk2::Image and Gtk2::Label instance, after that, add the Gtk2::HBox to the Gtk2::Button class object to create a picture button with a label next to it.
We can set the cursor with the set_cursor method when it enter and leave the button. This simulates the effect of a hyper link, as we will see in the sample program.
The button also feature the mnemonic functionality that was discussed as part of Chapter 6.
Gtk2::Frame This class is one of those cosmetic classes, it is a Gtk2::Bin subclass, so you can (just like Gtk2::Window) add only one child widget to it.
Other cosmetic classes include Gtk2::HSeparator and Gtk2::VSeparator.
The Gtk2::Frame does not have much features.
You can set its outline with the $frame->set_shadow_type ($type).
Another point worth mentioning is the label that traditionally accompany the Gtk2::Frame.( widget = Gtk2::Frame->new ($label=undef) or $frame->set_label ($label=undef) ) This is actually only a default. You can add any widget to the frame where the label usually resides. This is done by the $frame->set_label_widget ($label_widget) method.
This feature is also available on the tabs of Gtk2::NoteBook. This allows you to add a Gtk2::HBox containing a label and a close button for instance to each tab.
In our sample program we add a Gtk2::CheckButton to it. We will manipulate the appearance of the checkbutton as it gets clicked.
This class will be looked at in depth later on. In our sample program, we will create an instance of it by getting its data from a file.
Gtk2::ScrolledWindow When one of your widget's length may change or you don't know what its initial size may be, or it is simply to long to fit onto your screen, you can put this long or wide widget into a Gtk2::ScrolledWindow.
As you might have guessed, this is also a Gtk2::Container subclass. There are basically three methods of importance.
$scrolled_window->set_policy ($hscrollbar_policy, $vscrollbar_policy) This can take the option of always , automatic or never. The rule of thumb is to set the side you want to scroll to automatic and the one you don't want to scroll to never.
$scrolled_window->set_shadow_type ($type) This is used to make the scrolled window stand more out using a choice between none , in, etched-in and etched-out.
$scrolled_window->add_with_viewport ($child) When you want to add a NON-SCROLLING widget, you do not use the Gtk2::Container's add method. This is the method you should use to add the NON-SCROLLING child widget.
[1]
Gtk2::Gdk::Cursor The cursor may change depending over which widget it is hovering. The Gtk2::Entry widget is an example where it will change. You can also specify what it should be.
In our sample program, we simulate the feel of a web browser by changing the cursor to a hand as soon as we enter the checkbutton's area, and change it back again as when we leave the checkbutton's area with the mouse.
$check_button->signal_connect('enter' => sub {$check_button->window->set_cursor($hand_cursor);});
You will notice that we call the window property of $check_button. This is Gtk2::Gdk::Window that we reference. We then use the set_cursor method to set the cursor. To get the cursor back to normal, you do not have to remember what it was previously, just set it to undef.
Thus, to set a cursor of a widget, we have to call its window property.
$check_button->signal_connect('leave' => sub {$check_button->window->set_cursor(undef);});
![]() | Please node that |
Gtk2::StockStock items are standard icons with labels that comes with Gtk+. A typical example is the "Ok" and "Cancel" buttons. This is powerful because the label change according to you language settings, making internationalization easier.
Stock items are special in the sense that, depending where it gets called, it may include a icon and a label, or just an icon. In our sample program, we call it to create a stock button. This includes the label to. If we create a Gtk2::Image from stock, we will not get the label with it.
They are them dudes from the movie "Dude, where's my car?", dude!
The program can be found here: 'Button Demo'
1 #! /usr/bin/perl -w 2 use strict; 3 4 use Glib qw/TRUE FALSE/; 5 use Gtk2 '-init'; 6 7 #standard window creation, placement, and signal connecting 8 my $window = Gtk2::Window->new('toplevel'); 9 $window->signal_connect('delete_event' => sub { Gtk2->main_quit; }); 10 $window->set_border_width(5); 11 $window->set_position('center_always'); 12 13 #this vbox will geturn the bulk of the gui 14 my $vbox = &ret_vbox(); 15 16 #add and show the vbox 17 $window->add($vbox); 18 $window->show(); 19 20 #our main event-loop 21 Gtk2->main(); 22 23 24 sub ret_vbox { 25 26 my $hand_cursor = Gtk2::Gdk::Cursor->new ('hand2'); 27 #create a Gtk2::VBox to pack a Gtk2::Frame in. The frame will contain 28 #a Gtk2::ScrolledWindow, which in turn will contain a Gtk2::VBox full 29 #of Gtk2::Buttons 30 my $sw; 31 my $vbox = Gtk2::VBox->new(FALSE,5); 32 33 my $frame = Gtk2::Frame->new(); 34 #to prove that a Gtk2::Frame can contain somethethig else 35 # than a label 36 my $check_button = Gtk2::CheckButton->new ("Click Here!"); 37 38 $check_button->set_active (TRUE); 39 $check_button->signal_connect (toggled => sub { 40 my $self = shift; 41 if ($self->get_active){ 42 # 'activate' the scrolled window and chance the checkbutton's 43 # appearance if the user checks the check button. 44 my $img_dude = Gtk2::Image->new_from_file("./pix/sweet.jpg"); 45 #add a touch of detail 46 $window->set_icon_from_file ("./pix/dude.jpg"); 47 $sw->set_sensitive (TRUE); 48 $check_button->set_label("Sweet, and what about mine?"); 49 $check_button->set_property('image'=>$img_dude); 50 51 }else{ 52 # 'gray out' the scrolled window and chance the checkbutton's 53 # appearance if the user un-checks the check button. 54 my $img_sweet = Gtk2::Image->new_from_file("./pix/dude.jpg"); 55 #add a touch of detail 56 $window->set_icon_from_file ("./pix/sweet.jpg"); 57 $sw->set_sensitive (FALSE); 58 $check_button->set_label("Dude, what does mine say?"); 59 $check_button->set_property('image'=>$img_sweet); 60 } 61 }); 62 $check_button->show; 63 $check_button->signal_connect('enter' => sub {$check_button->window->set_cursor($hand_cursor);}); 64 $check_button->signal_connect('leave' => sub {$check_button->window->set_cursor(undef);}); 65 66 $frame->set_label_widget ($check_button); 67 $frame->set_shadow_type ('out'); 68 #method of Gtk2::Container 69 $frame->set_border_width(10); 70 71 $sw = Gtk2::ScrolledWindow->new (undef, undef); 72 $sw->set_shadow_type ('etched-out'); 73 $sw->set_policy ('never', 'automatic'); 74 #This is a method of the Gtk2::Widget class,it will force a minimum 75 #size on the widget. Handy to give intitial size to a 76 #Gtk2::ScrolledWindow class object 77 $sw->set_size_request (300, 300); 78 #method of Gtk2::Container 79 $sw->set_border_width(10); 80 81 #create a vbox that will contain all the stock buttons 82 my $vbox_stock = Gtk2::VBox->new(FALSE,5); 83 foreach my $val(sort Gtk2::Stock->list_ids){ 84 my $btn_stock = Gtk2::Button->new_from_stock($val); 85 $vbox_stock->pack_start($btn_stock,FALSE,FALSE,4); 86 } 87 #add the vbox with all the stock buttons 88 $sw->add_with_viewport($vbox_stock); 89 90 $frame->add($sw); 91 92 $vbox->pack_start($frame,TRUE,TRUE,4); 93 $vbox->show_all(); 94 return $vbox; 95 }
To create a cursor object
my $hand_cursor = Gtk2::Gdk::Cursor->new ('hand2');To change the standard cursor as it enters the checkbutton, we connect the checkbutton's enter signal to an anonymous sub that will change our cursor.This is a signal from Gtk2::Button, but, since Gtk2::CheckButton is a subclass of Gtk2::Button, it also receives it. Remember that the set_cursor method has to be on the widget's window. ( Gtk2::Gdk::Window).
$check_button->signal_connect('enter' => sub {$check_button->window->set_cursor($hand_cursor);});To revert back we set the cursor to undef as the pointer leaves the button.
$check_button->signal_connect('leave' => sub {$check_button->window->set_cursor(undef);}); To do something when the Gtk2::CheckButton is checked or not, we connect to Gtk2::ToggleButton's toggled method and use a closure, where we can "gray out" the Gtk2::ScrolledWindow object, and set the image and caption of the checkbutton.
$check_button->signal_connect (toggled => sub {
my $self = shift;
if ($self->get_active){
# 'activate' the scrolled window and chance the checkbutton's
# appearance if the user checks the check button.
my $img_dude = Gtk2::Image->new_from_file("./pix/sweet.jpg");
#add a touch of detail
$window->set_icon_from_file ("./pix/dude.jpg");
$sw->set_sensitive (TRUE);
$check_button->set_label("Sweet, and what about mine?");
$check_button->set_property('image'=>$img_dude);
}else{
# 'gray out' the scrolled window and chance the checkbutton's
# appearance if the user un-checks the check button.
my $img_sweet = Gtk2::Image->new_from_file("./pix/dude.jpg");
#add a touch of detail
$window->set_icon_from_file ("./pix/sweet.jpg");
$sw->set_sensitive (FALSE);
$check_button->set_label("Dude, what does mine say?");
$check_button->set_property('image'=>$img_sweet);
}
});
![]() | To give your program a little personal touch, you can specify an icon to display on the window corner. This is done by |
If you want to create a buffer around a Gtk2::Container subclass, use the set_border_width method.
To set the minimum size of a widget, you use the Gtk2::Widget class's set_size_request method. This is nice to set initial sizes. We use it in our program to size the scrolled window.
$sw->set_size_request (300, 300);
To get a list of all the Gtk2::Stock id's use the Gtk2::Stock->list_ids method.
foreach my $val(sort Gtk2::Stock->list_ids){
my $btn_stock = Gtk2::Button->new_from_stock($val);
$vbox_stock->pack_start($btn_stock,0,0,4);
}We only want our scrolled window to scroll vertically, and not horizontally.
$sw->set_policy ('never', 'automatic');| [1] | Some widgets are "natively scrollable" -- that is, they support the If you use |