繁体   English   中英

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

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

我想问一下如何检测 Python tkinter.Canvas()中的标签。 我已经用一些基本的 canvas 对象设置了一个示例程序,并且所有这些对象都已分配给某个标签。 如果我点击 object 但不知道该怎么做,我想要的是获得该标签值。

例如,当我有此代码时:

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)

我想得到这些值,例如linesovalssquare_5_4square_7_1等。有人知道该怎么做吗? 哦:)

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()

正如@Matiiss 在评论中所建议的那样,您可以使用Canvas对象的tag_bind()方法将回调函数绑定到特定事件,例如按钮 1 单击它们。 下面的代码——基于你的——说明了这样的事情是如何完成的。

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()

您无需遍历所有项目即可获取 canvas 项目的标签。 canvas 上单击的任何项目都分配有“当前”标签。

您只需使用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