我正在开发一个tkinter应用程序,该应用程序使您可以在地图上单击并拖动,并使用滚轮进行放大和缩小。 UI在主地图下方还有一个较宽的部分,这导致应用程序比地图的Canvas
对象还要宽。
但是,对于单击和拖动事件和滚轮事件的位置,我得到了不同的坐标:就像我期望的那样,前者是画布内的坐标,而后者的x坐标增加了由底部较宽的对象添加的填充量。
这是一个最小的工作示例(使用所有动作,而不仅仅是单击并拖动):
#!/usr/bin/env python3
import tkinter as tk
class MainCanvas(tk.Canvas):
def __init__(self, tk_parent):
super().__init__(tk_parent, height=200, width=200, bg="green")
self.pack()
self.bind("<Motion>", self.print_move)
self.bind("<MouseWheel>", self.print_scroll) # For Mac
self.bind("<Button-4>", self.print_scroll) # For Linux
self.bind("<Button-5>", self.print_scroll) # For Linux
def print_coords(self, name, event):
print("{}: x: ({}, {}), y: ({}, {})".format(
name,
event.x, int(self.canvasx(event.x)),
event.y, int(self.canvasy(event.y))))
def print_move(self, event):
self.print_coords("moving", event)
def print_scroll(self, event):
self.print_coords("scroll", event)
class Bottom(tk.Canvas):
def __init__(self, tk_parent):
super().__init__(tk_parent, height=5, width=500, bg="red")
self.pack()
class GUI(tk.Frame):
def __init__(self, tk_parent):
super().__init__(tk_parent)
self.pack()
self.main = MainCanvas(self)
self.bottom = Bottom(self)
if __name__ == "__main__":
root = tk.Tk()
gui = GUI(root)
# Make an easy way to exit
for char in "wWqQ":
root.bind("<Control-{}>".format(char), lambda _: root.destroy())
root.mainloop()
和一些示例输出:
moving: x: (14, 14), y: (117, 117)
moving: x: (14, 14), y: (118, 118)
scroll: x: (164, 164), y: (118, 118)
scroll: x: (164, 164), y: (118, 118)
moving: x: (14, 14), y: (117, 117)
moving: x: (14, 14), y: (116, 116)
moving: x: (15, 15), y: (116, 116)
moving: x: (15, 15), y: (115, 115)
moving: x: (15, 15), y: (114, 114)
moving: x: (16, 16), y: (114, 114)
scroll: x: (166, 166), y: (114, 114)
scroll: x: (166, 166), y: (114, 114)
moving: x: (15, 15), y: (114, 114)
moving: x: (14, 14), y: (114, 114)
moving: x: (14, 14), y: (113, 113)
moving: x: (13, 13), y: (113, 113)
scroll: x: (163, 163), y: (113, 113)
scroll: x: (163, 163), y: (113, 113)
moving: x: (13, 13), y: (112, 112)
moving: x: (13, 13), y: (111, 111)
moving: x: (13, 13), y: (110, 110)
我希望对运动和滚动事件都具有相同的坐标系,但是如您所见,滚动事件向右移动了150个像素,这对应于左边的150个填充像素,这是由于底部的红色画布。使用.canvasx
和.canvasy
函数将事件移到画布的坐标系中无济于事。
任何想法如何解决此问题?我不想从滚动事件坐标中减去恒定的150个像素,因为整个窗口是可调整大小的,因此填充量可能会更大。
我在Mac(Mojave)上使用Python 3.7.2和tkinter 8.6版,尽管我的应用程序在具有多个Python和tkinter版本的Ubuntu上具有相同的行为。 (免责声明:我尚未在Ubuntu上尝试过MWE,但我希望它能正常工作。)
预先感谢您的帮助!