MrBlueSky wrote:
Hi, I've got a ScrolledCanvas object (sc) and have identified an item
on the canvas to which I wish to scroll. I've been reading around and
experimenting but with not much success.
So far I've managed to get the item's bbox using sc.bbox(item)
And got the proportion of the canvas that's visible using sc.xview()
and sc.yview()
And established the whole canvas bbox using sc.bbox(ALL)
I've even gone on to use some rudimentary maths to work out whether I
need to scroll, then used:
sc.xview_moveto(itemX)
But this is all rather messy and I've not yet got it working.
There must be an easier way?!
Thanks!
John
Done it! I realised that searching for the way to do this using Tk
would give me the clue.
For the benefit of any other poor soul who wants to do this, here's my
code:
def scrollToItem(self, item):
"""Work out whether the specified item is on display.
If it's not, scroll to it."""
# Bounding box for the item
xItemMin, yItemMin, xItemMax, yItemMax = self.bbox(item)
# Find out what proportion (0.0 to 1.0) of the canvas is
# currently on view
xViewMinP, xViewMaxP = self.xview()
yViewMinP, yViewMaxP = self.yview()
# Find out the full extent of the canvas
scrollRegionStr = self.component("canvas").cget("scrollregion")
scrollRegionElementsStr=scrollRegionStr.split(' ',4)
xCanvasMin = float(scrollRegionElementsStr[0])
yCanvasMin = float(scrollRegionElementsStr[1])
xCanvasMax = float(scrollRegionElementsStr[2])
yCanvasMax = float(scrollRegionElementsStr[3])
xRange = float(xCanvasMax - xCanvasMin)
yRange = float(yCanvasMax - yCanvasMin)
# Work out the canvas coordinates of the bit of the canvas
that's
# currently on view
xViewMin = float(xViewMinP)*xRange
xViewMax = float(xViewMaxP)*xRange
yViewMin = float(yViewMinP)*yRange
yViewMax = float(yViewMaxP)*yRange
if xItemMin < xViewMin:
newXViewP = float(xItemMin - xCanvasMin)/xRange
self.xview_moveto(newXViewP)
elif xItemMax > xViewMax:
newXViewP = float(xItemMax - xCanvasMin -
(xViewMax-xViewMin))/xRange
self.xview_moveto(newXViewP)
if yItemMin < yViewMin:
newYViewP = float(yItemMin - yCanvasMin)/yRange
self.yview_moveto(newYViewP)
elif yItemMax > yViewMax:
newYViewP = float(yItemMax - yCanvasMin -
(yViewMax-yViewMin))/yRange
self.xview_moveto(newYViewP)
(I'd still very much appreciate any critique of this!)
John