如何在点击时获得最近的 tkinter canvas 元素?
How to get closest tkinter canvas element on click?
我正在使用 tkinter 进行非常简单的 python 编程。我想在 canvas 上绘制一些矩形,然后当点击某个矩形时,显示该矩形的标签。我无法让它工作。问题似乎是,无论我点击 canvas,函数 get_closest returns 1。感谢任何帮助。这是我第一次使用 tkinter(就此而言 python),因此也欢迎对我的代码发表任何与问题本身无关的评论!
import tkinter as tk
myrecs = [[None for j in range(4)] for i in range(4)]
class application:
def __init__(self, parent):
self.parent = parent
self.frame = tk.Frame(self.parent)
self.frame.grid(row=0)
self.quitbutton = tk.Button(self.frame, text = "Quit", command = lambda:quit())
self.quitbutton.grid(row=0, column = 0, sticky=tk.W + tk.E)
self.canvas = tk.Canvas(self.frame, width=200, height=200, bg = "blue")
self.canvas.bind("<ButtonPress-1>", self.buttonclick)
self.canvas.grid(row=1, columnspan = 2)
self.tag = self.canvas.create_text(10, 150, text="", anchor="nw")
self.makebutton = tk.Button(self.frame, text = "Make nice canvas", command = self.makecanvas)
self.makebutton.grid(row=0, column = 1, sticky = tk.W + tk.E)
def makecanvas(self):
for i in range(4):
for j in range(4):
myrecs[i][j] = self.canvas.create_rectangle(20*i, 20*j, 20*(i+1), 20*(j+1), tags=("rectangle", "i"+str(i), "j"+str(j)))
def buttonclick(self, event):
cnv = self.canvas
item = cnv.find_closest(cnv.canvasx(event.x), cnv.canvasy(event.y))[0]
tags = cnv.gettags(item)
cnv.itemconfigure(self.tag, text=tags[0])
if __name__ == "__main__":
root = tk.Tk()
root.title("Test")
app = application(root)
root.mainloop()
find_closest
returns 1
表示它正在查找您在 canvas 中创建的第一个元素,在本例中为 create_text
。
奇怪的是,当您 create_text
和 text=""
时,它似乎超越了您的所有其他元素。通过 text=" "
的简单修复,它现在可以在点击时找到壁橱矩形。
对于其他元素,当您分配 option=""
时,它实际上 禁用 (据我所知)该选项,而不是使用其默认值,您是主动告诉 tcl
解释器不要使用它。这可以在 create_rectangle(..., outline="")
等其他元素中观察到,其中默认的 outline="black"
将不再适用,您甚至不会得到轮廓。我有一种感觉 text=""
会产生类似的效果,并且由于某种原因基本上覆盖了整个 canvas 区域,所以它导致 find_closest
总是 return 该元素。也许如果你幸运的话@BryanOakley(tcl 专家)可以参与后端推理。
事实上,如果您尝试 find_above(item)
,您会注意到 text
始终低于您之后绘制的其他元素。
简而言之:
# Change this:
self.tag = self.canvas.create_text(10, 150, text="", anchor="nw")
# To this:
self.tag = self.canvas.create_text(10, 150, text=" ", anchor="nw")
我正在使用 tkinter 进行非常简单的 python 编程。我想在 canvas 上绘制一些矩形,然后当点击某个矩形时,显示该矩形的标签。我无法让它工作。问题似乎是,无论我点击 canvas,函数 get_closest returns 1。感谢任何帮助。这是我第一次使用 tkinter(就此而言 python),因此也欢迎对我的代码发表任何与问题本身无关的评论!
import tkinter as tk
myrecs = [[None for j in range(4)] for i in range(4)]
class application:
def __init__(self, parent):
self.parent = parent
self.frame = tk.Frame(self.parent)
self.frame.grid(row=0)
self.quitbutton = tk.Button(self.frame, text = "Quit", command = lambda:quit())
self.quitbutton.grid(row=0, column = 0, sticky=tk.W + tk.E)
self.canvas = tk.Canvas(self.frame, width=200, height=200, bg = "blue")
self.canvas.bind("<ButtonPress-1>", self.buttonclick)
self.canvas.grid(row=1, columnspan = 2)
self.tag = self.canvas.create_text(10, 150, text="", anchor="nw")
self.makebutton = tk.Button(self.frame, text = "Make nice canvas", command = self.makecanvas)
self.makebutton.grid(row=0, column = 1, sticky = tk.W + tk.E)
def makecanvas(self):
for i in range(4):
for j in range(4):
myrecs[i][j] = self.canvas.create_rectangle(20*i, 20*j, 20*(i+1), 20*(j+1), tags=("rectangle", "i"+str(i), "j"+str(j)))
def buttonclick(self, event):
cnv = self.canvas
item = cnv.find_closest(cnv.canvasx(event.x), cnv.canvasy(event.y))[0]
tags = cnv.gettags(item)
cnv.itemconfigure(self.tag, text=tags[0])
if __name__ == "__main__":
root = tk.Tk()
root.title("Test")
app = application(root)
root.mainloop()
find_closest
returns 1
表示它正在查找您在 canvas 中创建的第一个元素,在本例中为 create_text
。
奇怪的是,当您 create_text
和 text=""
时,它似乎超越了您的所有其他元素。通过 text=" "
的简单修复,它现在可以在点击时找到壁橱矩形。
对于其他元素,当您分配 option=""
时,它实际上 禁用 (据我所知)该选项,而不是使用其默认值,您是主动告诉 tcl
解释器不要使用它。这可以在 create_rectangle(..., outline="")
等其他元素中观察到,其中默认的 outline="black"
将不再适用,您甚至不会得到轮廓。我有一种感觉 text=""
会产生类似的效果,并且由于某种原因基本上覆盖了整个 canvas 区域,所以它导致 find_closest
总是 return 该元素。也许如果你幸运的话@BryanOakley(tcl 专家)可以参与后端推理。
事实上,如果您尝试 find_above(item)
,您会注意到 text
始终低于您之后绘制的其他元素。
简而言之:
# Change this:
self.tag = self.canvas.create_text(10, 150, text="", anchor="nw")
# To this:
self.tag = self.canvas.create_text(10, 150, text=" ", anchor="nw")