2 votes

Les nouveaux éléments de Canvas ne sont pas ACTUELS

Je travaille sur une application qui nécessite le repositionnement des éléments du canevas. J'ai développé la classe grabbablePoint suivante mais les nouveaux points ne sont pas CURRENT à moins que je ne déplace la souris hors du point et ensuite de nouveau sur le point.

try:
    import tkinter as tk
except ImportError:
    import Tkinter as tk

class grabbablePoint:

    def __init__(self, canvas, x, y, r):
        if not(canvas.find_withtag(tk.CURRENT)):
            h = canvas.create_oval(x-r, y-r, x+r, y+r)
            canvas.tag_bind(h, '<Enter>', lambda e,hh=h: canvas.itemconfig(hh,fill='#FF0000'))
            canvas.tag_bind(h, '<Leave>', lambda e,hh=h: canvas.itemconfig(hh,fill=''))
            canvas.tag_bind(h, '<B1-Motion>', lambda e,hh=h: canvas.coords(hh,e.x-r,e.y-r,e.x+r,e.y+r))

if __name__ == '__main__':
    canv = tk.Canvas(width=400, height=300, bg='#CCCCFF')
    canv.bind('<Button-1>',lambda e: grabbablePoint(canv,e.x,e.y,3))
    canv.pack()
    tk.mainloop()

Par conséquent, si je clique sur un point avant de me déplacer et de revenir en arrière, un autre point apparaît juste au-dessus du premier. Bizarrement, je peux remédier à ce comportement indésirable en ajoutant un attribut de remplissage à create_oval ...

        h = canvas.create_oval(x-r, y-r, x+r, y+r, fill='#FF0000')

Maintenant, il fonctionne parfaitement. Quelqu'un peut-il m'expliquer ce qui se passe ici ? Pourquoi l'ajout d'un attribut déclenche-t-il CURRENT et pourquoi n'est-il pas défini autrement ?

1voto

FabienAndre Points 1972

Si vous dessinez votre forme sans remplissage, d'un point de vue Tkinter, vous n'êtes pas en vol stationnaire votre forme, vous survolez le fond. Sans remplissage, seul le trait de la forme est sensible aux événements de la souris (entrée, sortie, CURRENT...).

Vous pouvez contourner ce problème en utilisant une autre méthode de find_ famille : find_closest , find_overlapping .

Notez qu'en raison de l'échantillonnage des événements de la souris, vous pouvez également entrer dans une forme existante sans déclencher l'entrée (en sautant au-dessus du trait), et ainsi ne pas afficher votre arrière-plan qui implique que votre cercle ne bougera pas, et que vous créerez un autre cercle (cependant peu probable avec votre rayon et une souris).

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X