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

Python Discussion :

clic et logique booléenne avec tkinter


Sujet :

Python

  1. #1
    Membre très actif Avatar de Kurodiam
    Inscrit en
    Décembre 2013
    Messages
    208
    Détails du profil
    Informations forums :
    Inscription : Décembre 2013
    Messages : 208
    Par défaut clic et logique booléenne avec tkinter
    Bonjour,

    En ce moment , j'utilise tkinter et je voudrais créer un rectangle en faisant create_rectangle(...,options) .Mais je bloque sur un exercice qui nous demande : que lors du premier clic , une fonction qui dessine le rectangle doit retourner un rectangle de couleur rouge, et lors du 2ème clic , un rectangle de couleur verte , ensuite au prochain clic , le rectangle rouge doit étre et aprés vert ....(et ainsi de suite ) .
    J'ai pensé à la logigue booléenne , en initialisation une variable couleur , et l'incrémenter par la suite , en utilisant les conditions if , mais çà ne marche pas , je ne saisis pas le fonctionnement de tkinter et l'ampleur de l'argument event qui signifie évènement (pourtant , j'ai fait des heures de recherches)

    Voilà mon bout de code , et petite précision (il y'a une fonction manager() qui regroupe la position du clic et la fonction dessiner() , mais le noyau dur c'est la fonction dessiner()) :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    >>> couleur = 0
    >>> def dessiner(event):
    	     global couleur
    	     if couleur is 0 : c.create_rectangle(x - d, y - d, x + d, y + d, fill='red', outline="")
    ...          x, y = event.x, event.y
    ...          c = event.widget
    ...          d = 20             # diagonale
    ...          couleur = 1
                 if couleur is not 0 :c.create_rectangle(x - d, y - d, x + d, y + d, fill='green', outline="")
                 x, y = event.x, event.y
    	     c = event.widget
    	     d = 20
    En quoi mon raisonnement est faux ? J'ai un autre code concernant la parité en fonction d'un compteur des rectangles , mais c'est encore pire ....

  2. #2
    Expert confirmé

    Homme Profil pro
    Inscrit en
    Octobre 2008
    Messages
    4 307
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Belgique

    Informations forums :
    Inscription : Octobre 2008
    Messages : 4 307
    Par défaut
    Salut,

    La logique de TKinter t'échappe peut-être mais, moi, c'est la tienne qui m'échappe.

    Dans ta fonction:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
     
    >>> def dessine(event):
    	     global couleur
    	     if couleur is 0 : c.create_rectangle(x - d, y - d, x + d, y + d, fill='red', outline="")
    ...          ...
    ...          couleur = 1 # si tu changes la valeur de couleur ici
                 if couleur is not 0 : # forcément le deuxième rectangle sera dessiné par dessus le premier
    Simplifie toi la vie en mettant tes couleurs en constante au début de ton code.

    comme ça:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
     
    COLORS = ('red', 'green')
     
    def dessine(event):
        global couleur
        c.create_rectangle(x - d, y - d, x + d, y + d, fill=COLORS[couleur], outline="")

  3. #3
    Membre très actif Avatar de Kurodiam
    Inscrit en
    Décembre 2013
    Messages
    208
    Détails du profil
    Informations forums :
    Inscription : Décembre 2013
    Messages : 208
    Par défaut
    Ok! Merci mais le shell dit que la variable couleur n'est pas définie , voilà le message que j'obtiens :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    >>> Exception in Tkinter callback
    Traceback (most recent call last):
      File "/usr/lib/python2.7/lib-tk/Tkinter.py", line 1473, in __call__
        return self.func(*args)
      File "<stdin>", line 3, in manager
      File "<stdin>", line 6, in dessine
    Pourtant , lorsque j'écris aprés que couleur = 0 ou couleur = 1 , j'obtiens un carré de couleur rouge et aprés verte(çà fonctionne comme les index des listes avec COLORS[couleur]) mais justement ce n'est pas juste puisque c'est le clic de la souris qui doit déclencher l'action et non mon écriture sur le shell ...Je ne penses pas que des conditions vont régler ce soucis
    Je pourrais essayer en incluant des conditions sur la parité de x et y , l'une x et y est pair et l'autre x et y sont impaire mais je trouves que ceci ressemblerait plus à du bidouillage ...


    J'ai essayé une autre façon avec la logique booléenne mais là juste en incluant les couleurs :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    def dessine(event) :
    ...     c = event.widget
    ...     d = 20
    ...     x, y = event.x, event.y
    ...     green = True
    ...     if green == True :c.create_rectangle(x - d, y - d, x + d, y + d, fill="green", outline="")
    ...     else : c.create_rectangle(x - d, y - d, x + d, y + d, fill = 'red', outline="")
    ...
    En partant du principe que :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    >>> var = True
    >>> var
    True
    >>> var = not var
    >>> var
    False
    >>> var = not var
    >>> var
    True

  4. #4
    Expert confirmé

    Homme Profil pro
    Inscrit en
    Octobre 2008
    Messages
    4 307
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Belgique

    Informations forums :
    Inscription : Octobre 2008
    Messages : 4 307
    Par défaut
    Ok, je n'avais pas compris que la valeur de couleur était donnée à partir de la fonction.

    Dans ce cas, mets-la aussi dans l'espace de nom global en la fixant à zéro pour commencer.
    Tu peux utiliser True et False en lieu et place de 0 et 1.
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
     
    COLORS = ('red', 'green')
    couleur = False
    def dessine(event):
        global couleur
        c.create_rectangle(x - d, y - d, x + d, y + d, fill=COLORS[couleur], outline="")
        couleur = not couleur
    Si tu dois avoir plus de deux couleurs, tu utiliseras une simple incrémentation.

  5. #5
    Membre très actif Avatar de Kurodiam
    Inscrit en
    Décembre 2013
    Messages
    208
    Détails du profil
    Informations forums :
    Inscription : Décembre 2013
    Messages : 208
    Par défaut
    Un indice c'est lié à un tableau , on extrait par l'indice ...comme j'ai 3 couleurs , j'ai 3 indices (0,1,2), liste = ('red','blue','purple'), donc n = 2 ...
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
     
    >>> def cycle(n):
     
                   i = 0
                   while(True):     #  mais la boucle ne s'arréte jamais .
                                   i += 1
                                   print i % n

    Voilà ce que j'ai testé , ce qui est bizarre , c'est que j'obtiens en cliquant 3 fois , en premier un carré rouge puis violet puis vert et puis aprés que des carrés verts

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    >>> COLORS = ('red', 'green','purple')           # c'est un tuple .
    >>> couleur = 0
    >>> def dessine(event):
                global couleur
                c.create_rectangle(x - d, y - d, x + d, y + d, fill=COLORS[couleur], outline="")
                couleur = not couleur
                while(True) :
                                   couleur += 1
                                   couleur%2                     # n = 2

  6. #6
    Expert confirmé
    Avatar de fred1599
    Homme Profil pro
    Lead Dev Python
    Inscrit en
    Juillet 2006
    Messages
    4 061
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Meurthe et Moselle (Lorraine)

    Informations professionnelles :
    Activité : Lead Dev Python
    Secteur : Arts - Culture

    Informations forums :
    Inscription : Juillet 2006
    Messages : 4 061
    Par défaut
    @Kurodiam,

    On est dans un cas simple où tu peux te mettre aux classes, non? Ça éviterait ce moche mot clé global !

    Essayes aussi de mieux organiser ton code, par exemple une fonction getColor, ça serait sympatique,

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    >>> def getColor(value):...     COLOR = ('red', 'green', 'purple')
    ...     LENGTH = len(COLOR)
    ...     return COLOR[value%LENGTH]
    ... 
    >>> getColor(25)
    'green'
    Tant que c'est pas plus organisé dans ta tête, inutile de faire du GUI avec python... Ça fait pas plaisir, mais au moins c'est franc !

    Bonne continuation...

  7. #7
    Membre très actif Avatar de Kurodiam
    Inscrit en
    Décembre 2013
    Messages
    208
    Détails du profil
    Informations forums :
    Inscription : Décembre 2013
    Messages : 208
    Par défaut
    Logiquement , on peut faire appeler à une fonction déjà écrite dans une autre fonction , je parle de ta fonction getColor(value) ,cette dernière peut être réutiliser dans la fonction dessine ,et précisément fill , on mettra fill = getColor(value) :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    >>> def dessine(event) :
    ...     d = 21
    ...     c = event.widget
    ...     x, y = event.x, event.y
    ...     c.create_rectangle(x - d, y - d, x + d, y + d, fill=getColor(value), outline="")
    ...
    Par contre , je pense qu'il faut que je déclare ta fonction getColor() dans la fonction manager() sinon j'aurais tout le temps 'Type Error' ,ce qui est bien dans ta fonction getColor ,c'est qu'elle renvoie la couleur en une chaine et en fonction de l'ordre dans tuple COLOR .

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    >>> Exception in Tkinter callback
    Traceback (most recent call last):
      File "/usr/lib/python2.7/lib-tk/Tkinter.py", line 1473, in __call__
        return self.func(*args)
      File "<stdin>", line 2, in manager
      File "<stdin>", line 4, in getColor
    TypeError: unsupported operand type(s) for %: 'instance' and 'int'

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

Discussions similaires

  1. Réponses: 2
    Dernier message: 27/05/2007, 02h38
  2. IDLE plante avec Tkinter
    Par von_magnus dans le forum EDI/RAD
    Réponses: 2
    Dernier message: 06/07/2006, 07h20
  3. [Tkinter] Plusieurs fenêtre avec Tkinter
    Par cyrpaut dans le forum Tkinter
    Réponses: 2
    Dernier message: 04/01/2006, 22h24
  4. [Tkinter] Un petit souçis d'event avec Tkinter
    Par fire.stone dans le forum Tkinter
    Réponses: 4
    Dernier message: 29/10/2005, 20h56
  5. Réponses: 1
    Dernier message: 11/09/2005, 02h04

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