如何获取点击形状的标签

5 投票
3 回答
4132 浏览
提问于 2025-04-17 03:22

假设我在一个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)

这个布局就是把矩形按行和列的方式排列。

每个矩形都有一个特定的标签,像是 table1table2table30

当我点击矩形时,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 个回答

0

这个被接受的答案是正确的,解决了提问者的问题。我的重点是回答“如何获取形状的标签”这个问题,因为我在网上搜索时找到了这个帖子,但没有人回答这个部分的问题。在我们获取到项目的标签后,就可以使用它。

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')的返回值类型是字符串,如果有多个标签,标签名称会用空格分开。

4
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只用一个参数,也就是事件,来调用这个函数,而第二个参数就会用默认值。

9

你可以用下面的方式来引用你点击的对象:

event.widget.find_withtag("current")

这里的“current”标签是个特别的东西,它代表了鼠标下方最上面的那个对象。

撰写回答