Попробовав около получаса, я нашел другое решение, которое кажется лучше:
self.canvas.xview_moveto(float(scroll_x+1)/img_width)
self.canvas.yview_moveto(float(scroll_y+1)/img_height)
img_width
и img_height
- размеры изображения.Другими словами, они являются полностью прокручиваемой областью.
scroll_x
и scroll_y
- координаты нужного верхнего левого угла.
+1
является магическим значением, чтобы оно работало точно (но должно применяться только, если scroll_x/y
неотрицательно)
Обратите внимание, чтотекущее измерение виджета не требуется, только измерение содержимого.
Это решение работает очень хорошо, даже если изображение меньше размера виджета (и, следовательно, scroll_x/y
можетбыть отрицательным).
РЕДАКТИРОВАТЬ: улучшенная версия:
offset_x = +1 if scroll_x >= 0 else 0
offset_y = +1 if scroll_y >= 0 else 0
self.canvas.xview_moveto(float(scroll_x + offset_x)/new_width)
self.canvas.yview_moveto(float(scroll_y + offset_y)/new_height)