Как получить ближайший элемент холста tkinter по клику?

Я делаю очень простое программирование на Python с использованием tkinter. Я хочу нарисовать несколько прямоугольников на холсте, а затем, когда кто-то нажимает на определенный прямоугольник, показать теги этого прямоугольника. Я не могу заставить его работать. Кажется, проблема в том, что где бы я ни щелкал на холсте, функция get_closest возвращает 1. Любая помощь приветствуется. Я впервые работаю с tkinter (и python в этом отношении), поэтому любые замечания о моем коде, которые не связаны с проблемами, также приветствуются!

import tkinter as tk

myrecs = [[None for j in range(4)] for i in range(4)]

class application:
    def __init__(self, parent):
        self.parent = parent
        self.frame = tk.Frame(self.parent)
        self.frame.grid(row=0)
        self.quitbutton = tk.Button(self.frame, text = "Quit", command = lambda:quit())
        self.quitbutton.grid(row=0, column = 0, sticky=tk.W + tk.E)
        self.canvas = tk.Canvas(self.frame, width=200, height=200, bg = "blue")
        self.canvas.bind("<ButtonPress-1>", self.buttonclick)
        self.canvas.grid(row=1, columnspan = 2)
        self.tag = self.canvas.create_text(10, 150, text="", anchor="nw") 
        self.makebutton = tk.Button(self.frame, text = "Make nice canvas", command = self.makecanvas)
        self.makebutton.grid(row=0, column = 1, sticky = tk.W + tk.E)

    def makecanvas(self):
        for i in range(4):
            for j in range(4):
                myrecs[i][j] = self.canvas.create_rectangle(20*i, 20*j, 20*(i+1), 20*(j+1), tags=("rectangle", "i"+str(i), "j"+str(j)))    

    def buttonclick(self, event):
        cnv = self.canvas
        item = cnv.find_closest(cnv.canvasx(event.x), cnv.canvasy(event.y))[0]
        tags = cnv.gettags(item)
        cnv.itemconfigure(self.tag, text=tags[0])  

if __name__ == "__main__":
    root = tk.Tk()
    root.title("Test")
    app = application(root)
    root.mainloop()

1 ответ

Решение

find_closest возвращается 1 означает, что он находит самый первый элемент, который вы создали на холсте, который в данном случае является create_text,

Как ни странно, когда ты create_text с text="" кажется, обгоняет все остальные ваши элементы. С простым исправлением text=" " теперь он будет определять расположение прямоугольников в шкафу по щелчкам.

С другими элементами, когда вы назначаете option="" на самом деле он отключает (насколько я знаю) опцию, поэтому вместо использования значений по умолчанию вы активно говорите tcl интерпретатор, чтобы не использовать его. Это можно наблюдать в других элементах, таких как create_rectangle(..., outline="") в котором по умолчанию outline="black" больше не будет применяться, и вы даже не получите план. у меня есть ощущение text="" дает аналогичный эффект и по какой-то причине в основном покрывает всю область холста, поэтому он вызывает find_closest всегда возвращать этот элемент. Возможно, если вам повезет, @BryanOakley (эксперт по tcl) может вмешаться в бэкэнд-рассуждения.

На самом деле, если вы пытались find_above(item) вы заметите, что text последовательно ниже ваших других элементов, нарисованных впоследствии.

Короче:

# Change this:
self.tag = self.canvas.create_text(10, 150, text="", anchor="nw") 

# To this:
self.tag = self.canvas.create_text(10, 150, text=" ", anchor="nw") 
Другие вопросы по тегам