Tom's Guide > Forum > Programmation > [Python] Récupérer une valeur d'un rectangle dans Tkinter

[Python] Récupérer une valeur d'un rectangle dans Tkinter

Forum Programmation : [Python] Récupérer une valeur d'un rectangle dans Tkinter

TomsGuide.com : 800 000 inscrits répondent à toutes vos questions high-tech et informatique. Pour obtenir de l'aide, inscrivez-vous gratuitement !
Mot :    Pseudo :           
 

Bonjour, j'ai récupéré ce petit bout de code dans un guide:

Code :
  1. def mouseDown(self, event):
  2.         "Op. à effectuer quand le bouton gauche de la souris est enfoncé"
  3.         if self.snap:
  4.             self.currObject =None
  5.             # event.x et event.y contiennent les coordonnées du clic effectué :
  6.             self.x1, self.y1 = event.x, event.y
  7.             # <find_closest> renvoie la référence du dessin le plus proche :
  8.             self.selObject = self.can1.find_closest(self.x1, self.y1)
  9.             # modification de l'épaisseur du contour du dessin :
  10.             self.can1.itemconfig(self.selObject, width =3)
  11.             # <lift> fait passer le dessin à l'avant-plan :
  12.             self.can1.lift(self.selObject)
  13.             print self.selObject




Il permet, lorsque l'on clique dans un canvas avec des objets (rectangle, cercle, ligne), de sélectionner l'objet le plus près du clic de souris.


Maintenant, ce que j'essayais de faire, c'est de créer un quadrillage où l'on puisse cliquer avec un effet de snap (la souris se colle aux coordonnés ronds, en gros si on pointe sur 15.998 elle se collera sur 16. (Il existe des façon plus simple de faire un snapping, mais j'aimerais tester celle là)

Donc ayant fait un quadrillage, et placé un petit rectangle à chaque croisement de lignes, l'événement le plus proche représente le petit rectangle le plus proche (à moins que l'utilisateur ne clique délibérément sur une ligne, ce qui est un problème...). Maintenant l'objet self.selObject est un tupple représentant le numéro d'apparition du rectangle. Pas très pratique...

Est ce qu'il est possible d'aller chercher, disons les coordonnés bbox de l'événement associé au tupple self.selObject. Parce que self.selObject n'est pas le rectangle, mais qu'un numéro pointant vers ce rectangle.

Pour info, je laisse le code complet en dessous de mon message.







Code :
  1. # -*- coding: cp1252 -*-
  2. "Création de prisme de pression avec trappes"
  3. # Importation des modules externes
  4. from Tkinter import *
  5. # Importation module interne
  6. class ModPrism(Frame):
  7.     def __init__(self, boss=None, hauteur=700, largeur=1000):
  8.         Frame.__init__(self,borderwidth = 0)
  9.         self.boss = boss
  10.         self.h = hauteur
  11.         self.w = largeur
  12.         self.flw = float(self.w - 320)
  13.         self.flh = float(self.h - 20)
  14.         self.can1 = Canvas(self,bg='white',height=self.h,width=self.w-300)
  15.         self.can2 = Canvas(self,bg='white',height=self.h,width=300)
  16.         self.can1.grid(row=0,column=0)
  17.         self.can2.grid(row=0,column=1)
  18.         self.can1.grid_propagate(False)
  19.         self.can2.grid_propagate(False)
  20.         self.can1.bind("<Button-1>", self.mouseDown)
  21.         self.can1.bind("<Button1-Motion>", self.mouseMove)
  22.         self.lab00 = Frame(self.can2,bg="white" )
  23.         self.lab00.grid(column=0,row=0,padx=5,pady=5)
  24.         self.weNbCasesLg=Entry(self.lab00)
  25.         self.weNbCasesHt=Entry(self.lab00)
  26.         Label(self.lab00,text="Nombres de Colones",bg="white" ).grid(
  27.             column=0,row=0)
  28.         Label(self.lab00,text="Nombres de Rangées",bg="white" ).grid(
  29.             column=0,row=1)
  30.         self.weNbCasesLg.grid(column=1,row=0)
  31.         self.weNbCasesHt.grid(column=1,row=1)
  32.         a=Button(self.can2,text='Lancement',command=self.activation)
  33.         a.grid(column=0,row=2)
  34.     def activation(self):
  35.         self.snap = 1
  36.         self.can1.delete(ALL)
  37.         self.nbCasesLg = int(self.weNbCasesLg.get())
  38.         self.nbCasesHt = int(self.weNbCasesHt.get())
  39.         nbNoeudsTotaux = (self.nbCasesLg+1)*(self.nbCasesHt+1)
  40.         intervaleHt = self.flh/self.nbCasesHt
  41.         intervaleLg = self.flw/self.nbCasesLg
  42.         self.points = [0]*nbNoeudsTotaux
  43.         self.pointsX = []
  44.         self.pointsY = []
  45.         for i in range(self.nbCasesHt+1):
  46.             self.can1.create_line(10,i*intervaleHt+10,self.flw+10,
  47.                                   i*intervaleHt+10)
  48.         for i in range(self.nbCasesLg+1):
  49.             self.can1.create_line(i*intervaleLg+10,10,i*intervaleLg+10,
  50.                                   self.flh+10)
  51.        
  52.         for i in range(self.nbCasesLg+1):
  53.             for j in range(self.nbCasesHt+1):
  54.                 self.points[i*self.nbCasesLg+j] = self.can1.create_rectangle(i*
  55.                                             intervaleLg+7,j*intervaleHt+7,i*
  56.                                             intervaleLg+13,j*intervaleHt+13,
  57.                                             fill="blue" )
  58.     def mouseDown(self, event):
  59.         "Op. à effectuer quand le bouton gauche de la souris est enfoncé"
  60.         if self.snap:
  61.             self.currObject =None
  62.             # event.x et event.y contiennent les coordonnées du clic effectué :
  63.             self.x1, self.y1 = event.x, event.y
  64.             # <find_closest> renvoie la référence du dessin le plus proche :
  65.             self.selObject = self.can1.find_closest(self.x1, self.y1)
  66.             # modification de l'épaisseur du contour du dessin :
  67.             self.can1.itemconfig(self.selObject, width =3)
  68.             # <lift> fait passer le dessin à l'avant-plan :
  69.             self.can1.lift(self.selObject)
  70.             print self.selObject
  71. if __name__ == '__main__':
  72.     root = Tk()
  73.    
  74.     ecran = ModPrism(root)
  75.     ecran.grid()
  76.     root.mainloop()





Liens sponsorisés
Inscrivez-vous ou connectez-vous pour masquer ceci.

À force de chercher, j'ai pu constater qu'on pouvait récupérer la valeur d'une propriété d'un objet Canvas à l'aide de

a = self.can1.itemcget(self.selObject, "fill" )

Ce que je ne comprends toujours pas, c'est pourquoi l'option dont on cherche la valeur doit être en guillemet lorsque l'on utilise la méthode itemcget(item, option)

Edit: Et comment faire pour récupérer les coordonnés de l'item ? bbox ne fonctionne pas comme option :ange:


Message édité par reveurduciel le 16-07-2009 à 17:43:39
Répondre à reveurduciel

Les options sont entre guillemets, parce que derrière il y a un dictionnaire.

Pour changer les coordonées, ce n'est pas dans les options. Il faut utiliser coords(item, x0, y0, x1, y1)
http://www.pythonware.com/library/ [...] tangle.htm

------------------------------ 6800A007B81300CD10B00131C989CF26880541
81F900FA750230EDBADA03ECA80875FBECA808
74FBE4603C0175DFB80300CD10B8004CCD21
Répondre à CRicky

Merci CRicky.

Mais je ne veux pas les changer, ça je sais le faire. Je veux en fait les obtenir. En effet, comme j'essais de faire un effet de snapping (la souris colle sur les coordonnés précise), j'ai rempli mon canvas de petites zones (des rectangles) et je récupère la zone la plus proche du clic de la souris.

Cette zone (ce rectangle) est donc une façon de créer une zone dans laquelle les coordonnés du clic de la souris seront arrondis à une telle valeurs.

Maintenant que j'ai le numéro de l'objet rectangle le plus proche, je cherche à obtenir les coordonnés de ce rectangle. Ensuite il me sera facile d'assigner une valeur x et y "snappé" à mon clic.

Répondre à reveurduciel

OK. C'est presque pareil, sur le widget canvas, tu fais un coords(item) et ça te retourne la liste des coordonnées.
http://www.pythonware.com/library/ [...] ethods.htm

------------------------------ 6800A007B81300CD10B00131C989CF26880541
81F900FA750230EDBADA03ECA80875FBECA808
74FBE4603C0175DFB80300CD10B8004CCD21
Répondre à CRicky

Merci beaucoup. Je croyais que cette méthode ne servait qu'à modifier les coordonnés, mais tu viens de m'apprendre qu'elle peut aussi retourner les coordonnés de l'item existant.

En relisant la référence, c'était bien marqué:


coords(item, *coords) [#]

Returns the coordinates for an item.

item
Item specifier (tag or id).
*coords
Optional list of coordinate pairs. If given, the coordinates will replace the current coordinates for all matching items.
Returns:
If no coordinates are given, this method returns the coordinates for the matching item. If the item specifier matches more than one item, the coordinates for the first item found is returned.

Merci encore :)

Répondre à reveurduciel
Tom's Guide > Forum > Programmation > [Python] Récupérer une valeur d'un rectangle dans Tkinter
Aller à :

Il y a 244 utilisateurs connus et inconnus. Pour voir la liste des connectés connus, cliquez ici.

Liens