通过其手柄在画布中查找小部件

时间:2020-05-21 07:04:26

标签: python tkinter tkinter-canvas

我想通过它们的手柄找到一些放置在画布上的矩形。例如,如果我在一个系列中有5个矩形位置,并且它们的句柄范围从25到30,则我想通过它们的句柄查找这些矩形并删除该矩形。

到目前为止,我已经看到了使用标签来查找矩形(或画布上的项目)的方法,但是标签对我不起作用,因为我将所有矩形都放置在一个循环中,并且似乎只有最后一个标签是与矩形相关联。而且由于可以使用诸如标记之类的句柄来唯一标识矩形,所以我想知道是否可以在给定范围的情况下找到它们?

感谢您的帮助

2 个答案:

答案 0 :(得分:1)

tkinter Canvas并非完全面向对象,也就是说,您不能直接在画布项目上直接调用该项目上的方法;您必须在画布对象上调用将找到该项目的方法,并修改其属性。这是通过商品ID或标签完成的。

但是,您可以创建一个OOP层,以实现所需的行为:在以下示例中,class CanvasObject将画布项目包装在一个可以调用的对象中。您必须包装要调用的canvas方法,以启用完整的行为。

该示例显示了如何使用Canvas.itemconfig方法执行此操作。

import tkinter as tk


class CanvasObject:
    id = 0
    def __init__(self, canvas, canvas_id):
        self.canvas = canvas          # keep a reference of the canvas
        self.canvas_id = canvas_id    # keep a reference of the item id on the canvas
        self.id = CanvasObject.id            # each CanvasObject has its own unique id
        CanvasObject.id += 1
        
    def itemconfig(self, **kwargs):
        self.canvas.itemconfig(self.canvas_id, kwargs)

        
root = tk.Tk()
canvas = tk.Canvas(root)
canvas.pack(expand=True, fill=tk.BOTH)

# create a CanvasObject from the canvas item
rec = CanvasObject(canvas, canvas.create_rectangle((10, 10), (50, 40), fill='', outline='black'))

# dot notation call is now possible directly on the CanvasObject
rec.itemconfig(fill='red', outline='blue')   

root.mainloop()

答案 1 :(得分:0)

由于我可以使用标记之类的句柄来唯一标识矩形...

那是不对的。如果您拥有画布项目的句柄,则无需查找它们。您可以直接使用这些句柄,假设“句柄”是指创建项目时返回的唯一标识符。

这是一个人为设计的示例,该示例以随机颜色创建100个矩形。它会保存所有绿色项目的句柄,并显示一个按钮,单击该按钮将删除绿色项目。

import tkinter as tk
import random

root = tk.Tk()
canvas = tk.Canvas(root, width=400, height=400, bg="black")
canvas.pack(fill="both", expand=True)
green_items = []
for i in range(100):
    x = random.randint(10, 390)
    y = random.randint(10, 390)
    fill = random.choice(["red", "green", "blue", "yellow"])
    item_id = canvas.create_rectangle(x,y, x+10, y+10, fill=fill)
    if fill == "green":
        green_items.append(item_id)

def delete_green():
    for item_id in green_items:
        canvas.delete(item_id)

button = tk.Button(root, text="Delete Green", command=delete_green)
button.pack()
root.mainloop()