424. How to place a background image in GtkEventBox - Part 2 - using GdkDrawable draw_pixbuf?

Problem

This is in response to Andreas' Post titled "Possible to add not tiled backgrounds".

Suppose you want to have a single background image that always stayed at the top right corner of a GtkEventBox (no matter how the user changes the window size) as shown below:

How to place a background image in GtkEventBox - Part 2 - using GdkDrawable draw_pixbuf?


Solution


Sample Code

Note: The following image files are required by the sample code below. Please save a copy of the image files and put them in the same directory where you store the sample code.

 ball_green3.png
 ball_blue3.png

1   
2   
3   
4   
5   
6   
7   
8   
9   
10   
11   
12   
13   
14   
17   
18   
19   
20   
21   
22   
23   
24   
25   
26   
29   
30   
31   
32   
33   
34   
35   
36   
37   
38   
39   
40   
41   
42   
43   
44   
45   
46   
47   
53   
55   
56   
57   
59   
60   
61   
62   
63   
64   
65   
<?php
$window = new GtkWindow();
$window->set_size_request(400, 240);
$window->connect_simple('destroy', array('Gtk','main_quit'));
$window->add($vbox = new GtkVBox());

// display title
$title = new GtkLabel("  Place a background image in GtkEventBox\n".
"Part 2 - using GdkDrawable::draw_pixbuf()");
$title->modify_font(new PangoFontDescription("Times New Roman Italic 10"));
$title->modify_fg(Gtk::STATE_NORMAL, GdkColor::parse("#0000ff"));
$title->set_size_request(-1, 40);
$vbox->pack_start($title, 0);
$vbox->pack_start(new GtkLabel(), 0);

$vbox->pack_start($hbox = new GtkHBox());

$eventbox_left = new GtkEventBox();
$hbox->pack_start($eventbox_left);
$eventbox_left->add($vbox_left = new GtkVBox());
$vbox_left->pack_start(new GtkLabel("This is left eventbox."));
$vbox_left->pack_start(new GtkLabel("The green ball is the bg image."));
$vbox_left->pack_start(new GtkLabel("Note that this eventbox"));
$vbox_left->pack_start(new GtkLabel("uses the default gray backgd color."));
$eventbox_left->connect('expose_event', 'expose_event', "ball_green4.png"); // note 1

$eventbox_right = new GtkEventBox();
$hbox->pack_start($eventbox_right);
$eventbox_right->add($vbox_right = new GtkVBox());
$vbox_right->pack_start(new GtkLabel("This is right eventbox."));
$vbox_right->pack_start(new GtkLabel("The blue ball is the bg image."));
$vbox_right->pack_start(new GtkLabel("Note that you can also set"));
$vbox_right->pack_start(new GtkLabel("backgd color for the eventbox!"));
$eventbox_right->modify_bg(Gtk::STATE_NORMAL, GdkColor::parse("#BAFFB3"));
$eventbox_right->connect('expose_event', 'expose_event', "ball_blue4.png"); // note 1

$window->show_all();
Gtk::main();

function expose_event($widget, $event, $img) {
    $pixbuf = GdkPixbuf::new_from_file($img); // note 2
    $w = $pixbuf->get_width();
    $h = $pixbuf->get_height();
    $dest_x = $widget->allocation->width - $w; // note 3
    $dest_y = 0;
    $widget->window->draw_pixbuf($widget->style->bg_gc[Gtk::STATE_NORMAL], 
        $pixbuf, 0, 0, $dest_x, $dest_y); // note 4

    if($widget->get_child() != null)
        $widget->propagate_expose($widget->get_child(), $event);
    return true;
}

?>

Output

As shown above.
 

Explanation

  1. Register for the signal 'expose_event'.
  2. Load the background image. This works with all standard image file format such as .gif, .jpg or .png.
  3. Calculate where to place the background image. Here we place the image at the op right corner of the GtkEventBox.
  4. Sets the background image.

Note

Try compare this method with that described in How to place a background image in GtkEventBox - Part 1 - tiled background image?

  • Did you notice that this method supports transparencies in .png and .gif file?
  • As we're drawing each image directly onto the underlying GdkWindow, there's no issue of tiled images.
  • You can set a different background color for the eventbox too, i.e. a colored background color + a background image.
  • Note that the image will always stay at the top right, no matter how the user changes the window size as shown below:

Related Links

Add comment


Security code
Refresh