【问题标题】:How do I detect tags of clicked objects in tkinter Canvas?如何在 tkinter Canvas 中检测点击对象的标签?
【发布时间】:2022-01-22 04:40:00
【问题描述】:

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

例如,当我有此代码时:

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 等。有人知道该怎么做吗? O:)

【问题讨论】:

    标签: python tkinter canvas tkinter-canvas


    【解决方案1】:

    您无需遍历所有项目即可获取画布项目的标签。画布上被点击的任何项目都分配有"current" 标签。

    您只需使用canvas.find_withtagcanvas.gettags 或将"current" 直接传递给gettags,它将返回与画布项关联的所有标签。

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

    【讨论】:

      【解决方案2】:

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

      它创建匿名的lambda 函数,调用通用的pick() 点击事件处理函数,并将原始事件对象加上当前与对象。

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

      【讨论】:

        【解决方案3】:

        您可以遍历画布上的所有项目 ID,获取它们的标签并绑定一个函数以单击该对象(如果您需要画布上的所有对象(在 for 循环之前创建)以这样做):

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

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 2022-01-15
          • 2021-02-15
          • 1970-01-01
          • 1970-01-01
          • 2011-12-20
          • 1970-01-01
          • 2012-09-19
          相关资源
          最近更新 更多