如何通过Tkinter Canvas.scale方法跟踪横向位移并修正coffset
Tkinter Canvas缩放时偏移量跟踪问题
我正在研究Tkinter Canvas组件的canvas.scale(tag, x, y, ds, ds)方法,发现它不需要配合对应的canvas.move(tag, dx, dy)方法就能移动画布元素。
我需要通过self.coffset = 这行代码跟踪缩放带来的横向位移:当矩形的四角滚动到画布原点位置时,偏移量应该是(0,0)、(0,40)、(40,0)或(40,40),但拖拽滚动后再进行缩放,偏移量就不再正确了。
import tkinter as tk class moveScale(tk.Tk): def __init__(self): super().__init__() self.canvas = tk.Canvas( self, highlightthickness = 0, borderwidth = 0, cursor = "crosshair") self.canvas.pack(fill = "both", expand = True) # 存储动态鼠标指针位置 self.xx = self.yy = 0 self.coffset, self.cscale = (0, 0), 1 self.canvas.create_rectangle(0, 0, 40, 40, fill = "") # 鼠标绑定 self.bind("<Motion>", self.motion) self.bind("<B1-Motion>", self.mover) self.bind("<MouseWheel>", self.scaler) def motion(self, ev): self.xx, self.yy = ev.x, ev.y def mover(self, ev): dx, dy = ev.x - self.xx, ev.y - self.yy self.xx, self.yy = ev.x, ev.y self.move("all", dx, dy) def move(self, tag, dx, dy): self.canvas.move(tag, dx, dy) cs = self.cscale self.coffset = (self.coffset[0] + dx * cs, self.coffset[1] + dy * cs) self.updatetitle() def scaler(self, ev): if ev.delta > 0: ds = 1.1 else: ds = 0.9 self.scale("all", ev.x, ev.y, ds) def scale(self, tag, x, y, ds): self.canvas.scale(tag, x, y, ds, ds) self.cscale *= ds # TODO: self.coffset = self.updatetitle() def updatetitle(self): self.title(f"Offset: {self.coffset}, Scale: {self.cscale}") main = moveScale() main.updatetitle() main.mainloop()
我找到的文档说明:
.scale(tagOrId, xOffset, yOffset, xScale, yScale) 根据对象到点P=(xOffset, yOffset)的距离缩放所有对象。缩放因子xScale和yScale基于1.0,即1.0表示不缩放。选中的每个对象的点都会移动,使其到P点的x距离乘以xScale,y距离乘以yScale。
此方法不会改变文本项的大小,但可能会移动它。
基于这个说明,我尝试了几种计算偏移量的方式,但都无效:
(self.coffset[0] * ds, self.coffset[1] * ds)- 代码形式:
px, py = self.coffset self.coffset = (x + (px - x) * ds, y + (py - y) * ds)
- 代码形式:
self.coffset = (px + (ds - 1) * (px - x), py + (ds - 1) * (py - y))
内容的提问来源于stack exchange,提问作者user21199884
相关产品推荐
相关产品推荐

