Beefy Boxes and Bandwidth Generously Provided by pair Networks
Syntactic Confectionery Delight
 
PerlMonks  

Tk: Scaling canvas objects

by perldough (Sexton)
on Jul 23, 2012 at 19:45 UTC ( #983230=perlquestion: print w/replies, xml ) Need Help??

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

I have a canvas named CW in which I have a picture and a whole bunch of overlain objects such as text and circles. I need to be able to zoom in on the picture and have the overlain objects stay at the same spot on the picture. I tried doing it like this.

#####----- Show zoomed picture -----##### # $zoom is number between -4 and 3; Negative for zoom-out and positiv +e for zoom-in as worked out in the conditional statement. # $img is the original image. # $zimg is the zoomed image. $zimg = $MW->Photo(); ($zoom > 0) ? $zimg->copy($img, -zoom => $zoom) : $zimg->copy($img, -subsample => ($zoom * -1)); $CW->createImage(0,0, -anchor => 'nw', -image => $zimg, -tags => 'dwg' +); ###-- Omited: Create objs in $CW w/ orig dims --### ###-- Scale objects --### $zfactor is one of (0.25, 0.3, 0.5, 1, 2, 3) my $zfactor = ($zoom > 0) ? $zoom : -1 / $zoom; $CW->scale('all', 0, 0, $zfactor, $zfactor);
The image zooms, but the objects don't change at all. Instead, I get the following error message for the last line ($CW->scale...):
Tk::Error: bad window path name "all" at review.pm line 335.
Tk callback for scale
RC::paint_Info at review.pm line 335
RC::__ANON__ at review.pm line 101
Tk callback for .toplevel.frame.labframe.border.frame1.radiobutton2
Tk::__ANON__ at C:/Perl/site/lib/Tk.pm line 250
Tk::Radiobutton::Invoke at C:/Perl/site/lib/Tk/Radiobutton.pm line 42
<Button-1>
(command bound to event)
Anyone know what I'm doing wrong here?

Replies are listed 'Best First'.
Re: Tk: Scaling canvas objects
by zentara (Archbishop) on Jul 24, 2012 at 09:28 UTC
    I don't know the source of your error message, but in general on a Tk Canvas, images and text fonts won't scale automatically. For instance this script shows scale working error free with the "all" tag, but the image and text must be manually zoomed, which I did not do. So the real question for me is, how did your image actually zoom as you claim The image zooms, but the objects don't change at all.

    Please show a simple working example otherwise.

    #!/usr/bin/perl use warnings; use strict; use Tk; use Tk::JPEG; my $width = 600; my $height = 600; my $mw = MainWindow->new( -background => 'lightgreen' ); $mw->geometry( $width . 'x' . $height . '+40+40' ); # first create a canvas widget my $canvas = $mw->Scrolled('Canvas', width => $width/1.3, height => $h +eight/1.3)->pack(); my $eightim = $mw->Photo(-data => get_img() ); my $one = $canvas->createOval(55, 20, 200, 190, -fill => 'blue', -outline=>'blue', -tags => ['blue'], -stipple => 'gray75', ); my $two = $canvas->createOval(105, 20, 250, 190, -fill => 'red', -outline=>'red', -tags => ['red'], -stipple => 'gray12', ); my $eight = $canvas->createImage( ($width * .5), ($height * .5) - 20, -image => $eightim, -anchor => 'center', -tags => ['8im'], ); my $testfont = $mw->Font(-family=> 'Arial', -size => 24); my $text = 'This is some text'; $canvas->createText(50,50, -text => $text, -anchor => 'nw', -font => $testfont ); $canvas->createRectangle(47,47,290,87); my $ebutton = $mw->Button(-text => 'Exit', -command => 'Tk::exit')->pack(); my $sbutton = $mw->Button(-text => 'Scale', -command => sub{ $canvas->scale('all', 0, 0, 1.5, 1.5); $canvas->configure(-scrollregion=>[$canvas->bbox +("all")]); })->pack(); MainLoop(); ########################################### sub get_img{ my $ima8= '/9j/4AAQSkZJRgABAQEASABIAAD/4QAWRXhpZgAATU0AKgAAAAgAAAAAAAD//gAXQ3JlY +XRlZCB3 aXRoIFRoZSBHSU1Q/9sAQwAFAwQEBAMFBAQEBQUFBgcMCAcHBwcPCwsJDBEPEhIRDxEREx +YcFxMU GhURERghGBodHR8fHxMXIiQiHiQcHh8e/9sAQwEFBQUHBgcOCAgOHhQRFB4eHh4eHh4eHh +4eHh4e Hh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4e/8AAEQgARQAxAwEiAAIRAQ +MRAf/E ABwAAAICAwEBAAAAAAAAAAAAAAAHBggCAwUEAf/EADkQAAEDAwEFBgMECwEAAAAAAAECAw +QABREG BxIhMYEIE0FhcZFRofAiIzJiFBVCUlOCkqKxwcLx/8QAFAEBAAAAAAAAAAAAAAAAAAAAAP +/EABQR AQAAAAAAAAAAAAAAAAAAAAD/2gAMAwEAAhEDEQA/AMa3RY0iXITHix3X3lcm20FSj0HGs7 +XCkXG5 RoEVO8/IdS22PMnGas/onSdp0jaEtRm2u+CMyJSgApZ8Tk8kjwHh65JBEwNmOtZaAsWcsp +IyO+eQ g9Uk5HUVnL2W62joKxaUvAc+7kNk+2cnpTF1Ftms0GUuPare9c9xRSXS6Gm1Ec8cCT7CtF +n22WyR JS3dLO/CbJx3rbwdA8yCEkD0zQJW4wZttkmNPiPxXxzbdQUq9jXmq199s9j1jYEtyEtSo7 +6N5h9H EpzyUk+H0KrHqmzSdP3+XaJR3nI690LxjfTgFKuoINBzKKKKCabE0NL2lWsOAHAdKc/ENL +Oacu2m S9F2cXNUclKndxpRH7qlgKHUZHWq66euj9lvkK6xgC5FeSsAnG8M8Un1GR1qzCX7Lr7Rzz +Ud/vIs xvu14/GyvmAR4KBAPt4UFWc545zw5/XpXzOOOcY86l+otnOrLRKW2LVInsg/YeiNl0KHoO +I6ivPZ 9A6vuchLLVjlR883JTZaQnzO9j5ZoG32eJMh7RDzDpKkRpi22vygpSopHlkk9ag3aJQ0nX +cctgby re2V4+O+4M+wFNvTlutWgdFhiTLQhiOlTsh9fDfWeZ8/AD0FV413f16m1RLuxSUNuKCWUH +9lCRhP U4yfM0HCooooM20LccDTaCtajupSBkqJ4AY8c/Cnnsx2Zy7Spu6XS6zIkpaQTGiulGE88O +KH4ufI YA8/CG7AbQ1cNaKlPpC0QI5eQCM/eEhKT0BJ9QKZG3S/SbLpBLMNwtyJ73cFY4FKACVY+Q +6mg6F+ 2j6RsslcR+5d++g7q246C4U+RVyz5ZzWm0bUNHXB9LH6xXEWrl+kNFCffiB1IqtIGBgE4H +Lj9cfP jR68c8+FBYXaTs7XqhJnQbzJVIA3248hzfjq8k8PsE/HjSBnxJUGa9DmsrZksq3HELHFJH +11507u zxfpc61zLJKeLgg7q2Co5IQrI3fQEf3egri9o+0tMXS23htCUrlIW07jxKMbpPxOFY/lFA +pKKKKB o9nGY21qmdEWQlT8TeRnxKVA49iT0qYdoW2PzdJR5sdtSzCkguADOEKGCffd96R2nLvKsN +7jXaGr D0Ze+ATgLGMFJ8iOHWrN6U1NZNW2kqiuNLUpG7IiO43kZGCFJPNPyNBVTIxzHvR4cOfhT/ +v2xuwT ZKn7dNk2zfOS2kBbY9ASCB1rTaditljvpduN0lzkpIPdpQGkn15n5ig8HZutbzbNzvDiFJ +ZeKGGC R+LGSr/n51h2lZbfd2WCD95l15Q+A+yB/umTdLnYNH2NK5TkeBEYQUsspwCfyoT4n/01Wz +XOo5Oq NRP3WQC2lQDbLROe7bGcD5k+pNBwqKKKA5ZPlW6JIkRXUvxH3Y7qRlK2llJHoQRiiigk8H +aTrWI2 ENX15aR/GbQ6f6lJJ+dZydpmt5SVNqvi0Jxx7thtJ9wkEUUUEXnzptxfMmdLkSXVcCt5wr +V7k15/ 8UUUBRRRQf/Z'; return $ima8; } ####################################### __END__

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

      Oh, the image only zooms because I deal with it separately by redrawing the image at the appropriate scale every time the canvas is zoomed.

      #####----- Show zoomed picture -----##### # $zoom is number between -4 and 3; Negative for zoom-out and positiv +e for zoom-in as worked out in the conditional statement. # $img is the original image. # $zimg is the zoomed image. $zimg = $MW->Photo(); ($zoom > 0) ? $zimg->copy($img, -zoom => $zoom) : $zimg->copy($img, -subsample => ($zoom * -1)); $CW->createImage(0,0, -anchor => 'nw', -image => $zimg, -tags => 'dwg' +);

      It's just the object scaling (that I try to do with $CW->scale()) that doesn't work and that gives me the aforementioned error.

      I'll try out your code (assuming it's tested) to ensure there is nothing wrong with my Tk. If there isn't I'm going to take the non-essential stuff out of my code and if it still doesn't work, I'll post it here!

      Thanks,

      Perldough
        I'll try out your code (assuming it's tested)

        Yes, it's well tested standard code. If you want to zoom text, you can configure the font object to use a scaled up point size. Rebuilding the font, just as you rebuild a new image.

        #!/usr/bin/perl use warnings; use strict; use Tk; require Tk::Font; #by originally by Chris Lamprecht my $MAIN = new MainWindow; my $canvas = $MAIN->Canvas()->pack(-expand => 'yes', -fill =>'both'); my $initial_fontsize = 24; my $scaling_factor = 1; my $l_text = "current scaling_factor : $scaling_factor"; my $helveticaStd = $MAIN->Font(-family=> 'Arial', -size => $initial_ +fontsize); my $text = 'This is some text'; $canvas->createText(50,50, -text => $text, -anchor => 'nw', -font => $helveticaStd); $canvas->createRectangle(47,47,290,87); for my$fac (0.8,1.2){ $MAIN->Button(-text => "Scale by $fac", -command => [\&scaling,$fac] )->pack; } $MAIN->Label(-textvariable=>\$l_text)->pack; MainLoop; sub scaling{ $scaling_factor *= $_[0]; $canvas->scale('all',0,0,$_[0],$_[0]); $helveticaStd->configure(-size=>$initial_fontsize * $scaling_factor +); $l_text = "current scaling_factor : $scaling_factor"; } __END__

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

      Alright, I think I've almost isolated the problem, but I feel no closer to a solution--without someone else's help, that is. :)

      Let me illustrate with 2 contrasting examples. These examples only test ovals because they are the objects that are truly causing me trouble.

      ========================= Ex. 1 =========================

      So first, when I run the whole out of one file, as you did in your example, I have no problem. The ovals scale properly and I get no error messages See code below.

      review.pm ========================= Ex. 2 =========================

      However, when I have a MW in a separate file which invokes the second window containing the canvas, the ovals don't scale and I get a whole wack of problems, including the original one.

      Here is the code:

      review_caller.pl review2.pm (beginning slightly different)

      Any ideas?

      Thank you very much for your time,
      Perldough
        When I run your review2.pm, I get your error. But I added a line which shows the problem. I can't figure out why it allowed you to create an Oval to begin with.?
        sub paint_Info{ #this shows the problem my ($MW, $CW, $zoom) = @_; print "\n\n@_\n\n"; $CW->createOval( 30, 30, 15, 15, -outline => 'red', -width => 2, -tags => ['INFO']); my $zfactor = ($zoom > 0) ? $zoom : -1 / $zoom; $CW->scale('all', 0, 0, $zfactor, $zfactor); }
        When you print out @_, you get
        MainWindow=HASH(0x7b8078) Tk::Frame=HASH(0xe2bfb0) 1
        You then take $_1 and try to run Canvas methods on it. Scale will not run on a Frame, that is a Canvas method.

        It just dawned on me! Your Frame is the Scrolled Frame the Canvas is in. Try getting the real canvas in your module. This fixes it! :-)

        sub paint_Info # ($MW, $Config) { my ($MW, $CW, $zoom) = @_; print "\n\n@_\n\n"; my $canvas = $CW->Subwidget('canvas'); $canvas->createOval( 30, 30, 15, 15, -outline => 'red', -width => 2, -tags => ['INFO']); my $zfactor = ($zoom > 0) ? $zoom : -1 / $zoom; $canvas->scale('all', 0, 0, $zfactor, $zfactor); }

        I'm not really a human, but I play one on earth.
        Old Perl Programmer Haiku ................... flash japh
Re: Tk: Scaling canvas objects
by Anonymous Monk on Jul 24, 2012 at 07:44 UTC

    Anyone know what I'm doing wrong here?

    Maybe you just need the latest version of Tk.pm?

    $ perl -MTk -e " tkinit->Canvas->pack->scale(qw{ all 0 0 0 0 }); MainL +oop; scale factor cannot be zero at C:/perl/site/5.14.1/lib/MSWin32-x86-mul +ti-thread/Tk.pm line 251. $ perl -MTk -e " tkinit->Canvas->pack->scale(qw{ all 0 0 1 1 }); MainL +oop; $ pmvers Tk 804.03

Log In?
Username:
Password:

What's my password?
Create A New User
Domain Nodelet?
Node Status?
node history
Node Type: perlquestion [id://983230]
Approved by marto
help
Chatterbox?
and the web crawler heard nothing...

How do I use this? | Other CB clients
Other Users?
Others about the Monastery: (3)
As of 2022-09-28 09:40 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?
    I prefer my indexes to start at:




    Results (124 votes). Check out past polls.

    Notices?