A little magnifying glass

KBK (19 July 2003) - A questioner in one of the newsgroups asked about how to create a widget that functions as a magifying glass, showing the content of another widget enlarged. The window capture facility of the Img extension, now available with ActiveTcl, combined with Tk's ability to do image scaling, can be combined readily to give this capability.

WikiDbImage magnify.jpg


# Let's begin by building a trivial GUI

 package require Tk
 package require Img
 
 wm geom . +0+0
 grid [text .t -width 20 -height 10 -cursor tcross -font {Courier 12}]
 .t insert end {   this widget
   contains several
   lines of text
   to demonstrate
   how to magnify
   a widget's
   content in 
   another
   widget.
 }
 
# We create an image to serve as the magnifier

 set mag [image create photo -width 192 -height 192]
 
# And we display the magnifier in another toplevel

 toplevel .mag
 wm title .mag Magnifier
 grid [label .mag.l -image $mag]
 wm geom .mag +400+0
 
# We establish a binding to make the magnifying glass update when the mouse moves

 bind .t <Motion> {magnify %W %x %y}

# And the 'magnify' procedure does all the work.

 proc magnify { w x y } {
 
     variable mag
 
     set wid [winfo width $w]
     set ht [winfo height $w]
     if { $x < 12 } {
        set x 12
     }
     if { $x > $wid - 13 } {
        set x [expr { $wid - 13 }]
     }
     if { $y < 12 } {
        set y 12
     }
     if { $y > $ht - 13 } {
        set y [expr { $ht - 13 }]
     }
 
     set from [image create photo -format window -data $w]
     $mag copy $from \
        -from [expr { $x - 12 }] [expr { $y - 12 }] \
               [expr { $x + 12 }] [expr { $y + 12 }] \
         -to 0 0 191 191 \
        -zoom 8
     rename $from {}
 }

Note that this procedure will work only for a single widget. If you need multiple widgets under your magnifier, another page discusses how to capture a window into an image.