tkinter .bind не получается получить адрес

При наведении мыши на один из созданных прямоугольников, выводится не верно какой он по номеру

from tkinter import *
tek_k = 0
id_k_new = 0
id_k_posl = 0
spisok_k = {}
class Glavn_okno(Tk):
    def __init__(self):
        super().__init__()
        self.geometry("500x500+200+0")
        self.resizable(0, 0)

        self.canvas = Canvas(self, width=573, height=561, highlightthickness=0)
        self.canvas.place(x=0, y=0)
        self.button = Button(self.canvas, text="Нажми", command=self.cikl_knop).place(x=400, y=450)
        self.bind('<Motion>', self.mouse_wheel_knop)


    def mouse_wheel_knop(self, event):
        global id_k_posl
        global spisok_k
        global id_k_new
        global tek_k
        for i in range(id_k_posl):
            tek_k = i + 1
            spisok_k["knop{}".format(i + 1)].bind("<Enter>", self.fun_nag)

        # Ф-я создания к
    def cikl_knop(self):
        global spisok_k
        global id_k_new
        global id_k_posl
        global tek_k
        id_k_new += 1
        for i in range(id_k_posl, id_k_new):
            spisok_k["knop{}".format(i + 1)] = Canvas(self.canvas, width=556, height=46, highlightthickness=0)
            spisok_k["knop{}".format(i + 1)].place(x=50, y=50 + 50 * i)
            spisok_k["knop{}".format(i + 1)].create_rectangle(0, 0, 150, 60,outline="#fb0", fill="#fb0")
            id_k_posl += 1

    def fun_nag(self, event):
        global tek_k
        global id_k_posl
        print("Текущая к", tek_k)

if __name__ == "__main__":
    osn = Glavn_okno()
    osn.mainloop()

Ответы (1 шт):

Автор решения: insolor

Несколько комментариев к вашему коду:

  1. Если перешли к ООП, то не используйте global - используйте поля объекта
  2. Не понятно зачем при нажатии кнопки создается новый холст. Получается куча холстов по одному прямоугольнику в каждом. Если вам просто нужен аналог кнопок, но без "рельефа" - используйте просто Label.
  3. Не понятен смысл цикла при нажатии кнопки. Нужно просто создать один прямоугольник без цикла.
  4. Привязку обработчиков к событиям нужно делать один раз - при создании объекта, а не в цикле при каждом движении мыши
  5. Давайте функциям и переменным понятные имена, не сокращайте слишком сильно

Ниже в примере создается один холст, при нажатии на кнопку создается один прямоугольник, каждый следующий смещен вниз от предыдущего. Для привязки события к фигуре (прямоугольнику) используется метод холста tag_bind, в качестве обработчика передается лямбда, через которую передается номер прямоугольника, который при срабатывании события передается уже внутрь настоящего обработчика (таким образом, обработчик "помнит", к какому объекту он привязан).

import tkinter as tk


class MainWindow(tk.Tk):
    def __init__(self):
        super().__init__()
        
        self.canvas = tk.Canvas(self)
        self.canvas.pack()
        tk.Button(self, text="Создать прямоугольник", command=self.new_rectangle).pack()
        
        self.rect_counter = 0
        self.rect_y = 0
    
    def new_rectangle(self):
        rectangle_id = self.canvas.create_rectangle(0, self.rect_y, 150, self.rect_y+60, outline="#fb0", fill="#fb0")
        self.rect_counter += 1
        self.canvas.tag_bind(rectangle_id, '<Enter>',
            lambda event, rect_number=self.rect_counter: self.on_hover(event, rect_number))
        
        self.rect_y += 70  # (высота прямоугольника + 10, чтобы был зазор)
        
    def on_hover(self, event, rect_number):
        print("Мышь над прямоугольником", rect_number)


if __name__ == "__main__":
    root = MainWindow()
    root.mainloop()
→ Ссылка