IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

Tkinter Python Discussion :

Selection d'une figure déja inscrite dans le Canevas


Sujet :

Tkinter Python

  1. #1
    Membre confirmé
    Inscrit en
    Mai 2008
    Messages
    146
    Détails du profil
    Informations forums :
    Inscription : Mai 2008
    Messages : 146
    Par défaut Selection d'une figure déja inscrite dans le Canevas
    Bonjour à vous,

    L'histoire commence quand je réussis à dessiner des figures géométriques dans mon canevas....(avec votre aide).

    Donc je ne screen pas mais il y a un canevas de 600x600, et à l'intérieur , 3 carrés, 4 triangles et 8 cercles (au hasard que j'ai moi meme dessiné).

    Maintenant je souhaiterais pouvoir sélectionner une figure au hasard pour pouvoir la déplacer ou la faire pivoter...

    Je pense avoir compris l'histoire des déplacements (merci G.Swinnen), mais le problème qui me trotte dans la tete est , comment vais je pouvoir selectionner une des figures à l'écran ?

    Le code est exactement le même qu'un précédent post sur comment dessiner un triangle dans un canevas.
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
     
    from Tkinter import *
     
    class Dessiner(Tk):
        def __init__(self):
            Tk.__init__(self)
     
            self.fig=StringVar()
            self.fig.trace("w", self.fig_callback)
     
            self.title("Dessiner: carre, triangle ou cercle")
     
            self.canvas=Canvas(self, bg="white", width=600, height=600)
            self.canvas.pack(side=TOP)
     
            frmbout = Frame(self) # Conteneur pour centrer les boutons
            frmbout.pack(side=TOP)
            Button(frmbout, text="Quit", command=self.destroy).pack(side=RIGHT, padx=5, pady=2, ipadx=2)
    	self.bcarre = Button(frmbout, text="Carre", fg="black", command=lambda: self.fig.set("Carre"))
    	self.bcarre.pack(side=RIGHT, padx=5, pady=2, ipadx=2)
    	self.bcercle = Button(frmbout, text="Cercle", fg="black", command=lambda: self.fig.set("Cercle"))
    	self.bcercle.pack(side=RIGHT, padx=5, pady=2, ipadx=2)
            self.btriangle = Button(frmbout, text="Triangle", fg="black", command=lambda: self.fig.set("Triangle"))
            self.btriangle.pack(side=RIGHT, padx=5, pady=2, ipadx=2)
     
            self.fig.set("Cercle") # Inutile d'initialiser self.fig plusieurs fois
     
            # Cela ne semble pas etre le sujet mais :
            # Il est aussi possible de gerer cela par evenement avec un self.fig=None comme flag
            # de l'état du bouton
            # Tu garde ton def clic
            # Tu fais un self.canvas.bind("<Motion>", modif) ou tu rajoute un test sur self.fig
            # Tu fais un bind self.canvas("<ButtonRelease-1>", self.clicoff) > def clicoff: self.fig=None
            # Cela te permet de vérifier la présence d'un item lors du clic pour le modifier par la suite. 
            self.canvas.bind("<ButtonPress-1>",self.clic)
            self.canvas.bind("<B1-Motion>",self.modif)
     
        def fig_callback(self, *args):
            if self.fig.get() == "Cercle":
                self.bcercle.config(fg="white")
                self.bcarre.config(fg="black")
                self.btriangle.config(fg="black")
     
            elif self.fig.get() == "Carre":
                self.bcercle.config(fg="black")
                self.bcarre.config(fg="white")
                self.btriangle.config(fg="black")
     
            elif self.fig.get() == "Triangle":
                self.bcercle.config(fg="black")
                self.bcarre.config(fg="black")
                self.btriangle.config(fg="white")
     
        def modif(self, event):
            # Pas besoin de reprendre les points x1 et y1. C'est le départ
            self.x2=event.x
            self.y2=event.y
     
            if self.fig.get() != "Triangle":
                self.canvas.coords(self.item, self.x1, self.y1, self.x2, self.y2)
            else:
                dist=self.x2 - self.x1 # Ton calcul pour le triangle n'étais pas bon.
                self.canvas.coords(self.item, self.x1-dist, self.y1+dist, self.x1, self.y1, self.x1+dist, self.y1+dist)
     
        def clic(self, event):
            self.x1=event.x
            self.y1=event.y
            if self.fig.get() == "Cercle":
                self.item=self.canvas.create_oval(self.x1, self.y1, self.x1, self.y1, fill="black")
            elif self.fig.get() == "Carre":
    	    self.item=self.canvas.create_rectangle(self.x1, self.y1, self.x1, self.y1, fill="black")
            elif self.fig.get() == "Triangle":
    	    self.item=self.canvas.create_polygon(self.x1, self.y1, self.x1, self.y1, self.x1, self.y1) # fill="black" inutile dans le cas du polygon.
     
    if __name__== "__main__":     
        fen=Dessiner()    
        fen.mainloop()
    J'ai codé à coté un script qui me dis où je me situe par rapport à l'axe des X et des Y... mais bon, ca ne me sert pas vraiment... Oo

    Merci d'avance !

    Edit : Lol je viens de m'en rendre compte, mais je ne compte pas voler le code ci-dessus... (abusé j'ai meme laissé les commentaires du monsieur :s).

  2. #2
    Membre chevronné
    Avatar de vincent.mbg
    Homme Profil pro
    Développeur Python
    Inscrit en
    Décembre 2007
    Messages
    327
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 38
    Localisation : France, Hérault (Languedoc Roussillon)

    Informations professionnelles :
    Activité : Développeur Python

    Informations forums :
    Inscription : Décembre 2007
    Messages : 327
    Par défaut
    Bonjour,

    le widget Canvas dispose des méthodes find_* pour ce genre de travail.
    par exemple :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
     
    catch(  self, event ) :
    <div style="margin-left:40px">print "id de ma figures", find_closest( event.x, event.y )</div>
    Pour l'évènement, tu pourrai utiliser Ctrl + clique gauche par exemple.
    Mon guide pour apprendre Tkinter - N'oubliez pas de consulter les FAQ Python ou de visiter mon blog

  3. #3
    Membre confirmé
    Inscrit en
    Mai 2008
    Messages
    146
    Détails du profil
    Informations forums :
    Inscription : Mai 2008
    Messages : 146
    Par défaut
    Merci du conseil, je vais voir ce que G.Swinnen me dit à ce propos.
    Je joins mon code des qu'il ressemblera à quelque chose.

    Heu juste pour info, ctrl + clic gauche ca s'écrit comment s'il vous plait ?
    self.canvas.bind("<CTRL + ButtonPress-1>", command=...) ??


    Merci.

  4. #4
    Membre confirmé
    Inscrit en
    Mai 2008
    Messages
    146
    Détails du profil
    Informations forums :
    Inscription : Mai 2008
    Messages : 146
    Par défaut
    Je me suis rendu compte que je n'utilisais pas le bouton droit, donc ça donne :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
     
    self.canvas.bind("<ButtonPress-2>", self.select)
     
    def select(self,event):
    		self.x1=event.x
    		self.y1=event.y
    		# <find_closest> renvoie la reference du dessin le plus proche :
    		self.selObject = self.find_closest(self.x1, self.y1)
    		# modification de l epaisseur du contour du dessin :
    		self.itemconfig(self.selObject, width =3)
    		# <lift> fait passer le dessin a l avant plan :
    		self.lift(self.selObject)
    ça ne fonctionne pas... :s

  5. #5
    Membre chevronné
    Avatar de vincent.mbg
    Homme Profil pro
    Développeur Python
    Inscrit en
    Décembre 2007
    Messages
    327
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 38
    Localisation : France, Hérault (Languedoc Roussillon)

    Informations professionnelles :
    Activité : Développeur Python

    Informations forums :
    Inscription : Décembre 2007
    Messages : 327
    Par défaut
    Pour "Ctrl + Bouton gauche" c'est

    <Control-Button-1>

    Pour savoir comment s'écrit un événement saisissez ceci dans python

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    help( Canvas.bind )
    Bonne continuation
    Mon guide pour apprendre Tkinter - N'oubliez pas de consulter les FAQ Python ou de visiter mon blog

  6. #6
    Membre confirmé
    Inscrit en
    Mai 2008
    Messages
    146
    Détails du profil
    Informations forums :
    Inscription : Mai 2008
    Messages : 146
    Par défaut
    Merci de ta réponse

  7. #7
    Membre confirmé
    Inscrit en
    Mai 2008
    Messages
    146
    Détails du profil
    Informations forums :
    Inscription : Mai 2008
    Messages : 146
    Par défaut
    Bonjour à vous,

    Je vous relance parce que j'ai un peu de mal avec le problème d'au-dessus..

    Ce que je ne comprends pas, c'est que je veux déplacer une figure,donc pouvoir la sélectionner au préalable et que find_closest me renvoie la reférence du dessin le plus proche, mais en quoi ca m'aide ?

    Merci d'avance.

  8. #8
    Membre Expert Avatar de PauseKawa
    Homme Profil pro
    Technicien Help Desk, maintenance, réseau, système et +
    Inscrit en
    Juin 2006
    Messages
    2 725
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Hérault (Languedoc Roussillon)

    Informations professionnelles :
    Activité : Technicien Help Desk, maintenance, réseau, système et +
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Juin 2006
    Messages : 2 725
    Par défaut
    Bonjour,

    Le sujet traine il me semble...

    Un (gros) indice.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    116
    117
    118
    119
    120
    121
    122
    123
    124
    125
    126
    127
    128
    129
    130
    131
    132
    133
    134
    135
    136
    137
    138
    139
    140
    141
    142
    143
    144
    145
    146
    147
    148
    149
    150
    151
    # -*- coding: cp1252 -*-
    from Tkinter import *
     
    class Dessiner(Tk):
        def __init__(self):
            Tk.__init__(self)
     
            self.title("Dessiner: carre, triangle ou cercle")
     
            self.fig=StringVar()
     
            self.canvas=Canvas(self, bg="white", width=600, height=600)
            self.canvas.pack(side=TOP)
            frmbout = Frame(self) # Conteneur pour centrer les boutons
            frmbout.pack(side=TOP)
            Button(frmbout, text="Quit", command=self.destroy).pack(side=RIGHT, padx=5, pady=2, ipadx=2)
            Button(frmbout, text="Clear", command=lambda: self.canvas.delete(ALL)).pack(side=RIGHT, padx=5, pady=2, ipadx=2)
            Button(frmbout, text="Delete", command=self.objdelete).pack(side=RIGHT, padx=5, pady=2, ipadx=2)
            self.bcarre = Button(frmbout, text="Carre", fg="black", command=lambda: self.fig.set("Carre"))
            self.bcarre.pack(side=RIGHT, padx=5, pady=2, ipadx=2)
            self.bcercle = Button(frmbout, text="Cercle", fg="black", command=lambda: self.fig.set("Cercle"))
            self.bcercle.pack(side=RIGHT, padx=5, pady=2, ipadx=2)
            self.btriangle = Button(frmbout, text="Triangle", fg="black", command=lambda: self.fig.set("Triangle"))
            self.btriangle.pack(side=RIGHT, padx=5, pady=2, ipadx=2)
     
            # Evenements
            self.canvas.bind("<ButtonPress-1>",self.clic) # Création d'une figure / déplacement si sélection.
            self.canvas.bind("<B1-Motion>",self.modif) # Modification d'une figure.
            self.canvas.bind("<ButtonPress-3>", self.select) # Sélection d'une figure existante.
            self.canvas.bind("<B3-Motion>",self.selfmodif) # Modification d'une figure existante.
     
            self.fig.trace("w", self.fig_callback)
            self.fig.set("Cercle")
            self.selObject=None
     
        def fig_callback(self, *args):
            if self.fig.get() == "Cercle":
                self.bcercle.config(fg="white")
                self.bcarre.config(fg="black")
                self.btriangle.config(fg="black")
     
            elif self.fig.get() == "Carre":
                self.bcercle.config(fg="black")
                self.bcarre.config(fg="white")
                self.btriangle.config(fg="black")
     
            elif self.fig.get() == "Triangle":
                self.bcercle.config(fg="black")
                self.bcarre.config(fg="black")
                self.btriangle.config(fg="white")
     
        def modif1(self, event):
            self.x2=event.x
            self.y2=event.y
            if self.selObject:
                ObjType=self.canvas.gettags(self.selObject)[0]
                if ObjType == "Carre" or ObjType == "Cercle":
                    self.canvas.coords(self.selObject, self.x1, self.y1, self.x2, self.y2)
                elif ObjType == "Triangle":
                    dist=self.x2 - self.x1
                    self.canvas.coords(self.selObject, self.x1-dist, self.y1+dist, self.x1, self.y1, self.x1+dist, self.y1+dist)
            else:
                if self.fig.get() != "Triangle":
                    self.canvas.coords(self.item, self.x1, self.y1, self.x2, self.y2)
                else:
                    dist=self.x2 - self.x1
                    self.canvas.coords(self.item, self.x1-dist, self.y1+dist, self.x1, self.y1, self.x1+dist, self.y1+dist)
     
        def modif(self, event):
            self.x2=event.x
            self.y2=event.y
            if self.fig.get() != "Triangle":
                self.canvas.coords(self.item, self.x1, self.y1, self.x2, self.y2)
            else:
                dist=self.x2 - self.x1
                self.canvas.coords(self.item, self.x1-dist, self.y1+dist, self.x1, self.y1, self.x1+dist, self.y1+dist)
     
        def clic(self, event):
            if self.selObject:
                # Une sélection est en cours : déplacement
                newposx=event.x
                newposy=event.y
                if self.selObject:
                    ListCords = self.canvas.coords(self.selObject)
                    ObjType=self.canvas.gettags(self.selObject)[0]
     
                    x1=ListCords[0]
                    y1=ListCords[1]
                    x2=ListCords[2]
                    y2=ListCords[3]
     
                    if ObjType != 'Triangle':
                        demilargeur=(x2-x1)/2
                        demihauteur=(y2-y1)/2
                        self.canvas.coords(self.selObject, newposx-demilargeur, newposy-demihauteur, newposx+demilargeur, newposy+demihauteur)
                    else:
                        x3=ListCords[4]
                        y3=ListCords[5]
                        demilargeur=(x3-x1)/2
                        if y2>y1: # Prise en compte du sommet
                            demihauteur=(y2-y1)/2
                            self.canvas.coords(self.selObject, newposx-demilargeur, newposy-demihauteur, newposx, newposy+demihauteur, newposx+demilargeur, newposy-demihauteur)
                        else:
                            demihauteur=(y1-y2)/2
                            self.canvas.coords(self.selObject, newposx-demilargeur, newposy+demihauteur, newposx, newposy-demihauteur, newposx+demilargeur, newposy+demihauteur)
                self.clearscreen()
            else:
                # Création d'une nouvelle figure
                self.clearscreen()
                self.x1=event.x
                self.y1=event.y
                if self.fig.get() == "Cercle":
                    self.item=self.canvas.create_oval(self.x1, self.y1, self.x1, self.y1, fill="black", tag='Cercle')
                elif self.fig.get() == "Carre":
                    self.item=self.canvas.create_rectangle(self.x1, self.y1, self.x1, self.y1, fill="black", tag='Carre')
                elif self.fig.get() == "Triangle":
                    self.item=self.canvas.create_polygon(self.x1, self.y1, self.x1, self.y1, self.x1, self.y1, tag='Triangle')
     
        def select(self, event):
            self.selObject = self.canvas.find_withtag(CURRENT)
            if self.selObject:
                self.canvas.itemconfig(self.selObject, fill='yellow')
                self.x1=event.x
                self.y1=event.y
            else:
                self.clearscreen()
     
        def clearscreen(self, event=None): # event=None car utilisé dans un bind
            self.selObject=None
            for items in self.canvas.find_all():
                self.canvas.itemconfig(items, fill='black')
     
        def objdelete(self):
            if self.selObject: self.canvas.delete(self.selObject)
            self.clearscreen()
     
        def selfmodif(self, event):
            # c'est le même code que modif() : A toi d'en faire une même et seule fonction ;) Indice : if self.selObject:
            if self.selObject:
                self.x2=event.x
                self.y2=event.y
                ObjType=self.canvas.gettags(self.selObject)[0]
                if ObjType == "Carre" or ObjType == "Cercle":
                    self.canvas.coords(self.selObject, self.x1, self.y1, self.x2, self.y2)
                elif ObjType == "Triangle":
                    dist=self.x2 - self.x1
                    self.canvas.coords(self.selObject, self.x1-dist, self.y1+dist, self.x1, self.y1, self.x1+dist, self.y1+dist)
     
    if __name__== "__main__":
        fen=Dessiner()    
        fen.mainloop()
    Tu remarqueras que j'ai rajouter les tags.

    @+

    Edit : Il y a sans doute plus simple.
    Pour la rotation avec un tag style 'h', 'b', 'd', et 'g' et un changement de tag à chaque rotation cela devrais le faire. Le plus dur c'est le triangle

  9. #9
    Membre confirmé
    Inscrit en
    Mai 2008
    Messages
    146
    Détails du profil
    Informations forums :
    Inscription : Mai 2008
    Messages : 146
    Par défaut
    Merci PauseKawa...
    Je bosse sur le code et je reviens.

    PS : Je peux sortir la tête de l'eau. Tu gères.

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. Réponses: 5
    Dernier message: 06/08/2012, 03h31
  2. Selection d'une figure dans un panneau avec la souris
    Par Geo34 dans le forum Agents de placement/Fenêtres
    Réponses: 2
    Dernier message: 16/12/2010, 17h25
  3. Selection d'une partie d image dans une figure
    Par airballman dans le forum Images
    Réponses: 3
    Dernier message: 26/04/2010, 09h20
  4. Selection d'une plage de cellules dans DatagridView [Vb.Net]
    Par papy75 dans le forum Windows Forms
    Réponses: 4
    Dernier message: 17/06/2008, 12h03
  5. Select sur une BD et Insert dans une autre
    Par arnolem dans le forum Langage SQL
    Réponses: 8
    Dernier message: 19/07/2006, 14h14

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo