http://www.perlmonks.org?node_id=530105


in reply to Perl-Gtk2::How to set a window background image.

Yeah, I feel your pain with trying to get to the lowlevel stuff in the docs. For what it's worth, I asked a similar question awhile back on the gtk-perl maillist, on whether you could set a style from a base64 encoded xpm contained within the file. The answer was "no". You would need to write it to a temp file, then incorporate it in as a style.

If you think about it, a background pixmap probably needs to be setup before anything can be drawn onto it. The normal method they are setting up, is to use styles, and have your pixmaps stored under a style name in the styles directory. So maybe it will take them a few years to get around to it. :-)

Another problem I've experienced with a Gdk window, is that it is not there until the window is mapped onto the screen. In the code below, if you try to get the gdkwindow in the main program, before show_all() is called, it will be undefined. The following is the closet I could get to what you want to do. It runs without error, but the background does not change, neither for a pixmap, nor a color. There probably is some command needed to redraw the window? I don't know, but if you find a way, please post it.

#!/usr/bin/perl use warnings; use strict; use Glib qw/TRUE FALSE/; use Gtk2 '-init'; my $rc_style = Gtk2::RcStyle->new; $rc_style->bg_pixmap_name('normal', 'bunny.xpm'); my $window = Gtk2::Window->new('toplevel'); $window->set_title('Embed test'); $window ->signal_connect( 'destroy' => \&delete_event ); $window->set_border_width(10); $window->set_size_request(500,500); $window->modify_style ($rc_style); my $vbox = Gtk2::VBox->new( FALSE, 6 ); $window->add($vbox); $vbox->set_border_width(2); my $hbox= Gtk2::HBox->new( FALSE, 6 ); $vbox->pack_end($hbox,FALSE,FALSE,0); $hbox->set_border_width(2); $vbox->pack_end (Gtk2::HSeparator->new, FALSE, FALSE, 0); my $button = Gtk2::Button->new_from_stock('gtk-quit'); $hbox->pack_end( $button, FALSE, FALSE, 0 ); $button->signal_connect( clicked => \&delete_event ); my $button1 = Gtk2::Button->new('Set BG'); $hbox->pack_end( $button1, FALSE, FALSE, 0 ); $button1->signal_connect( clicked => \&set_bg ); my $vbox1 = Gtk2::VBox->new( 0, 5 ); $vbox->pack_end ($vbox1, TRUE, TRUE, 0); my $btn = Gtk2::Button->new_from_stock('gtk-quit'); $btn->signal_connect( 'clicked' => \&delete_event ); $window->show_all(); Gtk2->main; ##################################### sub delete_event { Gtk2->main_quit; return FALSE; } ########################################## sub set_bg{ my @z_xpm = ( '20 3 2 1', ' c None', '+ c #1A1A1A', '+ + + + + + + + + + ', '+ + + + + + + + + + ', '+ + + + + + + + + + ',); my $gdkwindow = $vbox->window; print "$gdkwindow\n"; #my $colormap = Gtk2::Gdk::Colormap->get_system; my $colormap = $window->get_default_colormap; my $pixmap = Gtk2::Gdk::Pixmap->colormap_create_from_xpm_d (undef, $colormap, undef, @z_xpm ); # my $black = Gtk2::Gdk::Color->new (0,0,0); # $gdkwindow->set_background($black); $gdkwindow->set_back_pixmap($pixmap); $window->show_all(); }

I'm not really a human, but I play one on earth. flash japh

Replies are listed 'Best First'.
Re^2: Perl-Gtk2::How to set a window background image.
by turo (Friar) on Feb 14, 2006 at 17:38 UTC

    I was very upset and discouraged ... and when i was resigned to open and xpm image, load it to a pixmap, and then load it with the Gtk2::RcStyle as a background image ...
    when i received your reply ...
    The use of an XPM hardcoded into an array was like a deją vu ... I took my last breath and said i'm going to make the last effort ... and an hour after ... tachan!!!!!

    I can load any image (jpeg, png ... and all those supported by the gdkPixbuf) to a background. Here is the code, modified from the one you submitted (i've only change the set_bg function ...)

    #!/usr/bin/perl use warnings; use strict; use Glib qw/TRUE FALSE/; use Gtk2 '-init'; my $rc_style = Gtk2::RcStyle->new; $rc_style->bg_pixmap_name('normal', 'bunny.xpm'); my $window = Gtk2::Window->new('toplevel'); $window->set_title('Embed test'); $window ->signal_connect( 'destroy' => \&delete_event ); $window->set_border_width(10); $window->set_size_request(500,500); $window->modify_style ($rc_style); my $vbox = Gtk2::VBox->new( FALSE, 6 ); $window->add($vbox); $vbox->set_border_width(2); my $hbox= Gtk2::HBox->new( FALSE, 6 ); $vbox->pack_end($hbox,FALSE,FALSE,0); $hbox->set_border_width(2); $vbox->pack_end (Gtk2::HSeparator->new, FALSE, FALSE, 0); my $button = Gtk2::Button->new_from_stock('gtk-quit'); $hbox->pack_end( $button, FALSE, FALSE, 0 ); $button->signal_connect( clicked => \&delete_event ); my $button1 = Gtk2::Button->new('Set BG'); $hbox->pack_end( $button1, FALSE, FALSE, 0 ); $button1->signal_connect( clicked => \&set_bg ); my $vbox1 = Gtk2::VBox->new( 0, 5 ); $vbox->pack_end ($vbox1, TRUE, TRUE, 0); my $btn = Gtk2::Button->new_from_stock('gtk-quit'); $btn->signal_connect( 'clicked' => \&delete_event ); $window->show_all(); Gtk2->main; ##################################### sub delete_event { Gtk2->main_quit; return FALSE; } #### sub set_bg{ #### PNG & Pixbuff :-) my $values; my ($widget, $context, @other_params) = @_; my $colormap = $window->get_default_colormap; my $pixbuff = Gtk2::Gdk::Pixbuf->new_from_file("figure.png"); my $graphicContext = Gtk2::GC->get(Gtk2::Gdk::Visual->get_best_depth, $colormap, $values); $pixbuff->render_to_drawable($widget->get_parent_window, $graphicContext, 0,0,0,0,500,500,'normal',0,0); }

    The conclusion, is:
    In X11 programming, you can draw anything to any 'drawable' window (i'm not an expert, but this is correct), With the help of Gtk2::Widget::get_parent_window we obtain a Gtk2::Gdk::Window which is a Gtk2::Gdk::Drawable. Once we got a drawable window, i think we can do almost anything with it (low level :') ... and low docummented)

    Okay, alls seems to be fine, but i have other problem now; how i obtain a Gtk2::Gdk::Window without waiting to the execution of the callback function? ... We need a kind of casting function!!!! ... Ideas?


    Cheers
    turo



    (... thanks zentara!!! ...)

    perl -Te 'print map { chr((ord)-((10,20,2,7)[$i++])) } split //,"turo"'
      Hi, I think you are on the right track. I was experimenting with a Drawable area. I tried your code, but I am getting segmentation faults. :-( I'm using Gtk+2.8.11. Anyways, I will experiment with your code, and hope I can get it to go.

      Alot of the problem, is the non-intuitive nature of the Gtk2 objects, somethings can be written on, and somethings are only containers. It might be smart of you to ask muppet on the gtk-perl maillist. If anyone knows, it would be him.


      I'm not really a human, but I play one on earth. flash japh