如何获取点击形状的标签
假设我在一个Tkinter应用程序中创建了一个画布。
在这个画布上,我画了几个矩形。
我最想知道的是用户点击了哪个矩形,这才是我最关心的。不过,我尝试过一些方法,觉得可能有解决办法。
这是我的布局:
for x in range(1,6):
for y in range(1,7):
tableNumber = y + 6*(x-1)
w.create_rectangle((table.xSeparation + table.width) * y - table.width,
(table.ySeparation + table.height) * x - table.height,
(table.xSeparation + table.width)*y,
(table.ySeparation + table.height) * x,
fill="brown", tags="table" + str(tableNumber))
w.tag_bind("table" + str(tableNumber), '<Button-1>', do)
这个布局就是把矩形按行和列的方式排列。
每个矩形都有一个特定的标签,像是 table1
、table2
到 table30
。
当我点击矩形时,do
函数会被执行。
假设 do
函数的内容是这样的:
def do(event):
print "click"
现在每次点击矩形时,控制台都会显示一个“click”。
我希望能获取到被点击的矩形的标签,这样我就可以做一些事情,比如:
def do(event):
print str(theTagOfTheClickedRectangle)
所以我查看了可以调用的事件,这些事件包括:
- widget
- x, y
- x_root, y_root
- char
- keysym
- keycode
- num
- width, height
- type
但这些都没有明确指出我点击的是哪个矩形。
我考虑在 do
函数中添加更多参数:
w.tag_bind("table" + str(tableNumber), '<Button-1>', do(event, tag))
但这样似乎不太好用,可能是我没有正确使用 do
函数:
do(event, tag): #this doesn't work at all!!
print event.x
print tag
我希望这个问题说得清楚,如果我能像获取事件的 'x' 和 'y' 一样获取到标签,那就太方便了。
我现在能想到的唯一实际解决办法,就是通过计算 'event.x' 和 'event.y' 的值,来判断用户点击的是哪个矩形。不过,这样的做法对我想要实现的功能来说似乎有点复杂,尽管我以前也这样做过,并且确实有效。
我希望这个问题说得清楚,如果还有不明白的地方,请随时问我。
请注意,我并不拘泥于这些代码,我只是想找到这个问题的解决方案,最有效的方法都可以,即使不使用标签,或者换成其他类型的控件,或者任何更简单的方法。
3 个回答
这个被接受的答案是正确的,解决了提问者的问题。我的重点是回答“如何获取形状的标签”这个问题,因为我在网上搜索时找到了这个帖子,但没有人回答这个部分的问题。在我们获取到项目的标签后,就可以使用它。
canvas.itemconfig(id)
根据tkinter的文档,canvas.itemconfig
的用法和widget.config
是类似的。
我尝试了一下,返回的是一个字典,里面的属性作为键,值是一个五元组(应该是(option name, option database key, option database class, default value, current value))。如果你只对标签感兴趣,可以简单地调用
canvas.itemconfig(id,attr)
例如,如果我们想要获取项目的标签,
canvas.itemconfig(id,'tags')
这会立刻返回那个五元组,等同于
canvas.itemconfig(id)[attr]
注意:canvas.itemconfig(id,'tags')
的返回值类型是字符串,如果有多个标签,标签名称会用空格分开。
w.tag_bind("table" + str(tableNumber), '<Button-1>', do(event, tag))
应该改成
tag = "table" + str(tableNumber)
callback = lambda event, tag=tag: do(event, tag)
w.tag_bind(tag, '<Button-1>', callback)
这个lambda表达式创建了一个函数,它的第二个参数默认值是标签名称。Tkinter只用一个参数,也就是事件,来调用这个函数,而第二个参数就会用默认值。
你可以用下面的方式来引用你点击的对象:
event.widget.find_withtag("current")
这里的“current”标签是个特别的东西,它代表了鼠标下方最上面的那个对象。