#python #tkinter #events
Вопрос:
Когда я ловлю движение в виджете прямоугольника на холсте, он работает правильно, но когда я рисую положение мыши на холсте, событие whidet box больше не срабатывает
Чтобы увидеть проблему, просто раскомментируйте строки в функции canvmove.
Спасибо за вашу помощь.
from tkinter import *
class box():
def __init__(self, canvas, startx, starty, endx, endy, **opts):
self.canvas = canvas
self.startx, self.starty, self.endx, self.endy=startx, starty, endx, endy
self.index=self.canvas.create_rectangle(self.startx, self.starty, self.endx, self.endy, fill='orange')
self.tag="BoundingBox" str(self.index)
self.canvas.addtag(self.tag, 'withtag',self.index)
self.canvas.tag_bind(self.tag, '<Leave>', lambda event,t=self.tag:self.boxleave(event,self.tag))
self.canvas.tag_bind(self.tag, '<Motion>', lambda event:self.boxmotion(event,self.tag))
def boxleave(self, event, tag):
self.canvas.itemconfig(tag, fill="orange")
def boxmotion(self, event, tag):
# print("box motion ", event.x, event.y)
self.canvas.itemconfig(tag, fill="red")
def showcursorpos(self, event,t):
self.canvas.delete('mousepos')
def canvmove(event):
# print("canvas motion ", event.x, event.y)
dashes = [5, 25]
canvas.delete('mousepos')
# **********************************************************************
# WHEN ACTIVATING LINES BELOW THE BOXMOTION EVENT DOESN'T TRIGGER
# canvas.create_line(event.x, 0, event.x, 1000, dash=dashes, tags='mousepos')
# canvas.create_line(0, event.y, 1000, event.y, dash=dashes, tags='mousepos')
# **********************************************************************
root = Tk()
canvas = Canvas(root, background="white")
canvas.bind("<Motion>", canvmove)
label = Label(root)
for x in range(0, 200, 50):
for y in range(0, 200, 50):
# create unique tag
tag = 'rectangle_%s_%s' % (x,y)
rect = box(canvas, x,y,x 40,y 40)
canvas.grid()
label.grid()
root.mainloop()
Ответ №1:
Вот несколько иной способ достижения тех же или аналогичных результатов.
Он tag
состоит из цветов заливки, контура и активного заполнения и применяется к каждому прямоугольнику по мере их создания.
act
Метод обрабатывает пунктирные перекрестия, смещая линии на 3 точки.
Это позволяет взаимодействовать как с перекрестием, так и с прямоугольником.
import tkinter as tk
class box:
def __init__(self):
self.master = tk.Tk()
self.canvas = tk.Canvas(self.master)
self.canvas.grid(sticky = tk.NSEW)
self.rect = []
tag = dict(fill = "orange", outline = "black", activefill = "red")
for x in range(2, 202, 50):
for y in range(2, 202, 50):
self.rect.append(
self.canvas.create_rectangle(x,y,x 40,y 40, tag))
dashes = [5, 25]
self.itemLine1 = self.canvas.create_line(0, 0, 0, 1000,
dash = dashes, fill = "black")
self.itemLine2 = self.canvas.create_line(0, 0, 1000, 0,
dash = dashes, fill = "black")
self.canvas.bind( "<Motion>", self.act)
def act(self, ev):
self.canvas.coords( self.itemLine1, ev.x 3, 0, ev.x 3, 1000)
self.canvas.coords( self.itemLine2, 0, ev.y 3, 1000, ev.y 3)
app = box()
app.master.mainloop()
Это, возможно, лучшая замена метода act
.
Курсор включается, когда над прямоугольником и перекрестием выключены. Когда курсор не находится над прямоугольником, перекрестие включено, а курсор выключен.
def act(self, ev):
i = self.canvas.find_enclosed(ev.x-40, ev.y-40, ev.x 40, ev.y 40)
if i and i[0] in self.rect:
self.canvas.itemconfig(self.itemLine1, state = "hidden")
self.canvas.itemconfig(self.itemLine2, state = "hidden")
self.canvas["cursor"] = "crosshair"
else:
self.canvas["cursor"] = "none"
self.canvas.itemconfig(self.itemLine1, state = "normal")
self.canvas.itemconfig(self.itemLine2, state = "normal")
self.canvas.coords( self.itemLine1, ev.x, 0, ev.x, 1000)
self.canvas.coords( self.itemLine2, 0, ev.y, 1000, ev.y)
Ответ №2:
Я размышлял весь день и нашел способ добиться того, что мне было нужно : на самом деле, когда я рисую линии, я предполагаю, что курсор находится не на прямоугольнике, а на только что созданной линии… Итак, я попытался изменить способ рисования линий и нарисовать их вокруг положения мыши ( 3 x-y), а также триггера события !!
Спасибо за твой ответ, Дерек !!!
canvas.create_line(event.x, 0, event.x, event.y-3, dash=dashes, tags='mousepos')
canvas.create_line(event.x, event.y 3, event.x, 1000, dash=dashes, tags='mousepos')
canvas.create_line(0, event.y, event.x-3, event.y, dash=dashes, tags='mousepos')
canvas.create_line(event.x 3, event.y, 1000, event.y, dash=dashes, tags='mousepos')
Тогда решено 😉