Prev: Problem Setting Color in ttk combobox
Next: wm geometry
From: Shaun Deacon on 30 Apr 2010 15:15 > Hmmm... After a bit more testing, the above isn't quite accurate. It > seems the effect is more related to amount of canvas geometry found > "within" the rectangle I'm dragging out. As the rectangle surrounds > more geometry, the effect gets worse. Do you notice the same effect when the canvas is empty ? I have a similar function in one of my apps for doing an 'area selection'. I noticed that the rectangle re-display becomes less smooth the further I drag out, even when the canvas is empty - but not annoyingly so. The re-display is slightly less smooth when dragging over a large number of canvas items although, to be honest, not significantly different from the empty canvas case. BTW, I found that canvas performance, in general, is improved for very large numbers of items by limiting the number of added tags and using my own structures/lists of canvas items for doing canvas operations rather than using the tag mechanism. Shaun
From: Jeff Godfrey on 30 Apr 2010 15:45 On 4/30/2010 2:13 PM, Will Duquette wrote: > Well, you could try this: > > 1. Using Img, you can capture the visible area of the canvas as a > Tk image. > 2. Delete the contents of the canvas. (You're going to redraw it > anyway, once you get the rectangle, right?) > 3. Position the Tk image on the visible area of the canvas. Now > there's no geometry to slow things down. > 4. When they've selected the rectangle, delete the image, and redraw. Will, Thanks for the input. In my case though, it falls apart at #2, as I don't ever delete the canvas contents until I'm through with them. It takes too long to load the data for that to be workable. Currently, once I have the rectangle, zooming things is basically just a simple [move] and [scale] command - which is much lighter weight than reconstructing the contents of the canvas. Jeff
From: Jeff Godfrey on 30 Apr 2010 15:59 On 4/30/2010 2:15 PM, Shaun Deacon wrote: > >> Hmmm... After a bit more testing, the above isn't quite accurate. It >> seems the effect is more related to amount of canvas geometry found >> "within" the rectangle I'm dragging out. As the rectangle surrounds >> more geometry, the effect gets worse. > > Do you notice the same effect when the canvas is empty ? Hey Shaun, No, in my case the issue definitely doesn't exist when the canvas is empty. However, it's *very* noticeable when I'm dragging over 10's of thousands of items. > BTW, I found that canvas performance, in general, is improved for very > large numbers of items by limiting the number of added tags and using > my own structures/lists of canvas items for doing canvas operations > rather than using the tag mechanism. Yep, that's been exactly my experience too. For that very reason, I'm managing everything via an in-memory SQLite database, and avoiding canvas tags except for very specific (and mostly temporary) cases. That's unfortunate too, as I really like the canvas tagging mechanism. For this app though, due to the sheer amount of geometry I'm working with, I just can't afford to use them for general data management. Jeff
From: Aric Bills on 30 Apr 2010 16:20 On Apr 30, 1:45 pm, Jeff Godfrey <jeff_godf...(a)pobox.com> wrote: > On 4/30/2010 2:13 PM, Will Duquette wrote: > > > Well, you could try this: > > > 1. Using Img, you can capture the visible area of the canvas as a > > Tk image. > > 2. Delete the contents of the canvas. (You're going to redraw it > > anyway, once you get the rectangle, right?) > > 3. Position the Tk image on the visible area of the canvas. Now > > there's no geometry to slow things down. > > 4. When they've selected the rectangle, delete the image, and redraw. > > Will, > > Thanks for the input. In my case though, it falls apart at #2, as I > don't ever delete the canvas contents until I'm through with them. It > takes too long to load the data for that to be workable. > > Currently, once I have the rectangle, zooming things is basically just a > simple [move] and [scale] command - which is much lighter weight than > reconstructing the contents of the canvas. > > Jeff In that case, how about this procedure: 1. same as above 2. create a second canvas with the same dimensions as the first; put the image in this canvas and put this canvas in the place of the first canvas 3. let the users execute the drag on the second canvas 4. remove the second canvas and put the first one back In my test code (below), I get some brief flashing when I switch canvases, but the rectangle-dragging is smooth and responsive. package require img::window proc demo {} { variable c1 variable c2 toplevel .demo set c1 [canvas .demo.c1] set c2 [canvas .demo.c2] grid $c1 -sticky nsew # populate c1 set colorlist [list red orange yellow green blue purple] for {set i 0} {$i < 300000} {incr i} { set x1 [expr {int(rand() * [winfo reqwidth $c1])}] set y1 [expr {int(rand() * [winfo reqheight $c1])}] set x2 [expr {$x1 + 1}] set y2 [expr {$y1 + 1}] set color [lindex $colorlist \ [expr {int(rand() * [llength $colorlist])}]] $c1 create rectangle $x1 $y1 $x2 $y2 \ -width 0 \ -fill $color } # create bindings bind $c1 <Button-1> [list dragstart %x %y] bind $c2 <Motion> [list dragcontinue %x %y] bind $c2 <ButtonRelease-1> [list dragstop %x %y] } proc dragstart {x y} { variable dragx $x variable dragy $y variable dragitem variable dragimg variable c1 variable c2 # redimension c2 to the size of c1 $c2 configure -width [winfo width $c1] $c2 configure -height [winfo height $c1] # take a snapshot of the contents of c1; put it in c2 # also create the draggable rectangle set dragimg [image create photo \ -format window \ -data $c1] $c2 create image 0 0 \ -anchor nw \ -image $dragimg set dragitem [$c2 create rectangle \ $dragx $dragy $dragx $dragy] # replace c1 with c2 grid remove $c1 grid $c2 -sticky nsew } proc dragcontinue {x y} { variable dragx variable dragy variable dragitem variable c2 if {![info exists dragitem]} { return } $c2 coords $dragitem $dragx $dragy $x $y } proc dragstop {x y} { variable dragx variable dragy variable dragitem variable dragimg variable dragzone variable c1 variable c2 # remember final coordinates set dragzone [list $dragx $dragy $x $y] # put c1 back grid forget $c2 grid $c1 # clean up $c2 delete all image delete $dragimg unset dragx dragy dragitem dragimg } demo
From: Jeff Godfrey on 30 Apr 2010 16:43
On 4/30/2010 3:20 PM, Aric Bills wrote: > In that case, how about this procedure: Aric, The ingenuity of this group is always quite impressive... ;^) Thanks for working up an example. Unfortunately, when I tried it here is was completely non-responsive. Curious about why, I started digging and found the culprit: The call to [image create photo ...] takes 32 seconds to return (doh!). That's running an AS build (8.5.8) under Win7 x64 and using v1.4 of img::window. I really don't use the img extension, so I don't know if it needs to be updated, if it's (nearly) broken on Windows, or something else. Thoughts? Jeff |