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
→ Ссылка
Несколько комментариев к вашему коду:
- Если перешли к ООП, то не используйте
global- используйте поля объекта - Не понятно зачем при нажатии кнопки создается новый холст. Получается куча холстов по одному прямоугольнику в каждом. Если вам просто нужен аналог кнопок, но без "рельефа" - используйте просто
Label. - Не понятен смысл цикла при нажатии кнопки. Нужно просто создать один прямоугольник без цикла.
- Привязку обработчиков к событиям нужно делать один раз - при создании объекта, а не в цикле при каждом движении мыши
- Давайте функциям и переменным понятные имена, не сокращайте слишком сильно
Ниже в примере создается один холст, при нажатии на кнопку создается один прямоугольник, каждый следующий смещен вниз от предыдущего. Для привязки события к фигуре (прямоугольнику) используется метод холста 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()