revdiablo has asked for the wisdom of the Perl Monks concerning the following question:

First a little bit of setup. I am creating a simple image viewer, designed to be easily controlled via external programs. It waits on STDIN, and each time it receives a line of input, it attempts to use that as a filename. The viewer window will not size itself past set limits in either dimension, so if the image is too big it produces a set of scrollbars. This all works fine.

My problem comes when I attempt to modify the position of the scrollbars. I would like to center the scrollbars, so the middle portion of the image is viewable. Here's a bad ASCII diagram in case this is unclear:

.................... : : : ------------ : : | viewable | : : | portion | : : ------------ : : : ....................

The dotted lines are the image extents, and the viewable portion is what can be seen in the ScrolledWindow. The scrollbars should be adjusted so the viewable portion is cenetered on the image extents.

It seems like it should be a simple case of creating the appropriate Gtk2::Adjustment objects, and calling the set_hadjustment and set_vadjustment methods on my Gtk2::ScrolledWindow object. This does not change my scrollbars, however. If I check the values on the newly set objects, they contain what I put in them, yet the scrollbars are still unchanged. I thought, "perhaps the signal is not getting emitted properly," so then I tried adding Glib::Object->signal_emit($adjustment, "changed"); This produces a segfault.

At this point, I'm not sure what's going on. Am I setting the adjustments on the wrong object? I've been trying on my ScrolledWindow object, but there's also a Gtk2::Viewport object inside that. Should I be setting the adjustments on the Viewport object? That seems to have the same effect (i.e. none). I'm just running out of ideas. One thing to note is someone on IRC reported that the code works fine. Perhaps there's simply something wrong with my Gtk2-Perl install, or my Gtk2 library in general?

Here's the code:

#!/usr/bin/perl use strict; use warnings; use Gtk2 '-init'; use Gtk2::Helper; my @landscape = qw(800 600); my @portrait = qw(600 800); # Copyright (C) 2004 Carey Tilden <revdiablo@wd39.com> # This code is dual licensed. You may choose from one of the following +: # - http://creativecommons.org/licenses/by/1.0/ # - http://d.revinc.org/pages/license my ($mw, $sw) = create_widgets(); my $vp; Gtk2::Helper->add_watch(fileno(STDIN), 'in', \&load_image); Gtk2->main; sub load_image { exit if eof STDIN; my $file = <STDIN>; chomp $file; $sw->remove($vp) if defined $vp; my $img = Gtk2::Image->new_from_file($file); my $pb = $img->get_pixbuf; my ($x, $y) = ($pb->get_width, $pb->get_height); $vp = Gtk2::Viewport->new(undef, undef); $vp->add($img); $sw->add($vp); if ($x > $y) { $mw->resize($x > $landscape[0] ? $landscape[0] : $x + 2, $y > $landscape[1] ? $landscape[1] : $y + 2); } else { $mw->resize($x > $portrait[0] ? $portrait[0] : $x + 2, $y > $portrait[1] ? $portrait[1] : $y + 2); } # all these values are the same as default, except the first. thes +e # values are just for testing. the eventual plan is to adjust them # so the viewport is centered, but even with static values it # doesn't work. my $ha = Gtk2::Adjustment->new(50, 0, 1, 0.1, 0.9, 1); my $va = Gtk2::Adjustment->new(50, 0, 1, 0.1, 0.9, 1); $sw->set_hadjustment($ha); $sw->set_vadjustment($va); $mw->set_title("$file ${x}x${y}"); $mw->show_all(); return 1; } sub create_widgets { my $sw = Gtk2::ScrolledWindow->new(undef, undef); $sw->set_policy('automatic','automatic'); my $mw = Gtk2::Window->new; $mw->add($sw); return ($mw, $sw); }

Since this thing was designed to be controlled by an external program, using it might seem a little funky. Filenames come in via STDIN, and once STDIN is closed, the program exits. Here's an easy way to test it:

    perl -le "$|++; print and sleep 5 for qw(file1.jpg file2.jpg)" | perl imageviewer.pl

Replies are listed 'Best First'.
Re: setting scrollbar position of a Gtk2 ScrolledWindow
by tilly (Archbishop) on May 17, 2004 at 21:07 UTC
    I don't have Gtk2 installed, nor do I wish to install it at the moment, so I can only give generic advice.

    I happen to know that the Gnome libraries are undergoing a substantial change. (At least in Debian...) Therefore it is quite possible that due to a changing interface, something broke or works differently between two systems. Or even something as simple as 2 libraries aren't quite binary compatible and something needs to be recompiled.

    Therefore if you think that you are using the documented method, and if another person has reported that your code is doing what you think that it should, then my suggestion is that you are encountering a bug. You can try reinstalling the module, that might incorporate a bug fix, or might recompling something that needs it. If that doesn't work, then I would suggest that you send a bug report to the module maintainer, including as much detail as you can about what versions you have of things like the module and Gnome.

    If you didn't directly install the library, but instead got them in binary form (eg from rpms), then that could be your problem right there.

    Good luck tracking this down. Binary dependency problems are a real PITA to handle. Using Perl lessens the frequency with which you seem to encounter them, but doesn't lessen the pain of tracking down what went wrong.

Re: setting scrollbar position of a Gtk2 ScrolledWindow
by Anonymous Monk on Jan 27, 2008 at 16:13 UTC
    (Better late than never, i guess...) Your code was *almost* right. The problem is that the sizes of the widgets are not known until they are "realized" (made "real" by having their actual X windows created). You hardly ever need to create Adjustments, but can simply use the ones that get created automatically.
    $ diff -u monk.pl.orig monk.pl --- monk.pl.orig 2008-01-27 12:04:05.921317488 -0500 +++ monk.pl 2008-01-27 12:03:44.446582144 -0500 @@ -44,15 +44,18 @@ $y > $portrait[1] ? $portrait[1] : $y + 2); } - # all these values are the same as default, except the first. the +se - # values are just for testing. the eventual plan is to adjust the +m - # so the viewport is centered, but even with static values it - # doesn't work. - my $ha = Gtk2::Adjustment->new(50, 0, 1, 0.1, 0.9, 1); - my $va = Gtk2::Adjustment->new(50, 0, 1, 0.1, 0.9, 1); - - $sw->set_hadjustment($ha); - $sw->set_vadjustment($va); + # + # After the widgets are create and know their size, scroll to the + # middle of the image. Notice the halfway point is actually + # (upper-pagesize)/2, not upper/2 --- otherwise you'll attempt to + # scroll out of bounds. + # + $sw->signal_connect_after (realize => sub { + my $va = $_[0]->get_vadjustment; + $va->set_value (($va->upper - $va->page_size) / 2); + my $ha = $_[0]->get_hadjustment; + $ha->set_value (($ha->upper - $ha->page_size) / 2); + }); $mw->set_title("$file ${x}x${y}"); $mw->show_all();
Re: setting scrollbar position of a Gtk2 ScrolledWindow
by zentara (Cardinal) on May 19, 2004 at 14:24 UTC
    This dosn't answer your scrollbar question, but this is a dandy image viewer for gtk and gtk2, maybe it will help you. gtk-image-viewer

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