简体   繁体   English

如何检测 tkinter Canvas 中点击对象的标签?

[英]How do I detect tags of clicked objects in tkinter Canvas?

I would like to ask how can be detected the tags in Python tkinter.Canvas() .我想问一下如何检测 Python tkinter.Canvas()中的标签。 I have set up a sample program with some basic canvas objects and all of them have been assigned to some tag.我已经用一些基本的 canvas 对象设置了一个示例程序,并且所有这些对象都已分配给某个标签。 What I want is to get that tag value if I click on the object but have no idea how to do it.如果我点击 object 但不知道该怎么做,我想要的是获得该标签值。

For example when I have this code:例如,当我有此代码时:

import tkinter
canvas = tkinter.Canvas(width=800, height=400)
canvas.pack()

canvas.create_line(20, 100, 150, 350, tags="lines")
canvas.create_line(50, 20, 300, 20, tags="lines")
canvas.create_oval(200, 250, 300, 350, fill="yellow", tags="ovals")
canvas.create_oval(400, 250, 500, 350, fill="blue", tags="ovals")

for j in range(4):
    for i in range(10):
        canvas.create_rectangle(i * 70 + 10, j * 60 + 10, i * 70 + 60, j * 60 + 50, fill="lightblue", tags=f"square_{j}_{i}")

def click(coords):
    print(coords.x, coords.y)

canvas.bind("<Button-1>", click)

I would like to get these values such as lines , ovals , square_5_4 , square_7_1 etc. Does anyone have an idea how to do it please?我想得到这些值,例如linesovalssquare_5_4square_7_1等。有人知道该怎么做吗? O:)哦:)

You can just loop over all the item IDs on the canvas, get their tags and bind a function to clicking on that object (if you need that all of the objects (created before the for loop) on the canvas to do this): You can just loop over all the item IDs on the canvas, get their tags and bind a function to clicking on that object (if you need that all of the objects (created before the for loop) on the canvas to do this):

import tkinter as tk


root = tk.Tk()

canvas = tk.Canvas(root, width=800, height=400)
canvas.pack()

canvas.create_line(20, 100, 150, 350, tags="lines")
canvas.create_line(50, 20, 300, 20, tags="lines")
canvas.create_oval(200, 250, 300, 350, fill="yellow", tags="ovals")
canvas.create_oval(400, 250, 500, 350, fill="blue", tags="ovals")

for j in range(4):
    for i in range(10):
        canvas.create_rectangle(i * 70 + 10, j * 60 + 10, i * 70 + 60, j * 60 + 50, fill="lightblue", tags=f"square_{j}_{i}")


# loop over all items on the canvas, get their first tag (for simplicity) and bind that tag
# to clicking on the object and make that call the function that will print the tag name
# use a default value so that the correct tag is printed
for item_id in canvas.find_all():
    tag = canvas.gettags(item_id)[0]
    canvas.tag_bind(tag, '<Button-1>', lambda _, t=tag: print(t))

root.mainloop()

As @Matiiss suggest in a comment, you can use a Canvas object's tag_bind() method to bind callback functions to specific events such as button 1 clicks to them.正如@Matiiss 在评论中所建议的那样,您可以使用Canvas对象的tag_bind()方法将回调函数绑定到特定事件,例如按钮 1 单击它们。 The code below — based on yours — illustrates how something like that being done.下面的代码——基于你的——说明了这样的事情是如何完成的。

It creates anonymous lambda functions that call a generic pick() click event handling function and passes it the original event object plus the tag name currently associated with the object. It creates anonymous lambda functions that call a generic pick() click event handling function and passes it the original event object plus the tag name currently associated with the object.

import tkinter

def pick(event, tag):
    print(f'tag: {tag!r}, coords: {event.x}, {event.y}')

canvas = tkinter.Canvas(width=800, height=400)
canvas.pack()

canvas.create_line(20, 100, 150, 350, tags='lines')
canvas.create_line(50, 20, 300, 20, tags='lines')
canvas.tag_bind('lines', '<Button-1>', lambda event: pick(event, 'lines'))

canvas.create_oval(200, 250, 300, 350, fill='yellow', tags='ovals')
canvas.create_oval(400, 250, 500, 350, fill='blue', tags='ovals')
canvas.tag_bind('ovals', '<Button-1>', lambda event: pick(event, 'ovals'))

for j in range(4):
    for i in range(10):
        tag = f'square_{j}_{i}'
        canvas.create_rectangle(i*70 + 10, j*60 + 10, i*70 + 60, j*60 + 50,
                                fill='lightblue', tags=tag)
        canvas.tag_bind(tag, '<Button-1>', lambda event, tag=tag: pick(event, tag))

tkinter.mainloop()

You don't need to loop through all your items in order to get the tags of your canvas items.您无需遍历所有项目即可获取 canvas 项目的标签。 Any item on canvas that is clicked is assigned with "current" tag. canvas 上单击的任何项目都分配有“当前”标签。

You just need to use canvas.find_withtag along with canvas.gettags or pass "current" directly to gettags and it will return you all the tag associated with the canvas item.您只需使用canvas.find_withtagcanvas.gettags或直接将“current”传递给gettags ,它将返回与 ZFCC790C72A86190DE1ZB549D0DDC6F55 项目关联的所有标签。

import tkinter


canvas = tkinter.Canvas(width=800, height=400)
canvas.pack()

canvas.create_line(20, 100, 150, 350, tags="lines")
canvas.create_oval(400, 250, 500, 350, fill="blue", tags="ovals")

for j in range(4):
    for i in range(10):
        canvas.create_rectangle(i * 70 + 10, j * 60 + 10, i * 70 + 60, j * 60 + 50, fill="lightblue", tags=f"square_{j}_{i}")

def click(event):

    #currently_clicked = canvas.find_withtag("current")
    #if currently_clicked:
    print(canvas.gettags("current")) # the first index will contain your desired output
   
canvas.bind("<Button-1>", click)
canvas.mainloop()

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM