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 :

problème message d'erreur tkinter


Sujet :

Tkinter Python

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre du Club
    Femme Profil pro
    faussaire
    Inscrit en
    Avril 2014
    Messages
    8
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Âge : 95
    Localisation : France

    Informations professionnelles :
    Activité : faussaire

    Informations forums :
    Inscription : Avril 2014
    Messages : 8
    Par défaut problème message d'erreur tkinter
    Bonsoir à tous,
    Je suis entrain de programmer un petit jeu avec tkinter, et je tourne en rond depuis pas mal de temps! J'ai ici un code qui permet d'ouvrir 2 fenêtres: lorsqu'on clique sur la première, mon personnage se déplace jusqu'à un bâtiment, puis s'arrête. Là, une fenêtre s'ouvre avec un mini qcm. On y répond en écrivant un chiffre dans un "entry". Voici mon problème: dans le code que voici (j'ai essayé de le simplifier au max) ent est le nom de mon widget 'Entry'. Seulement un message d'erreur m'annonce que ent n'est pas défini. EN effet il est défini plus as dans le programme. J'ai donc essayé d'inverser, mais du coup c'est la fenêtre qui n'était plus définie, enfin bref, je tourne en rond comme je l'ai dit plus haut. Je m'adresse donc à vous car je m'avoue vaincue!
    Merci,
    P0lette

    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
    #Définitions deas variables du Sphinx
    GAGNE = "Bravo"
    PERDU = "Perdu."
    N = 4
     
    # traitement de l'Entry
    def getResult() :
     
        value = ent.get()
        #Si la réponse donnée n'est pas une valeure numérale
        if not value or not value.isdigit():
            raise ValueError ("Vous devez répondre par un chiffre!")
     
        n = int(value)
     
        ent.delete (0, END)
     
        if n== 4:
            labRes ['text'] = GAGNE
        else:
            labRes ['text'] = PERDU
            chantier = Tk()
            excuses = Label (chantier, text = """Jeu en cours de création, pour continuer
    l'aventure, recommencer le jeu et répondre 4 à l'épreuve du bac""")
            excuses.pack()
     
    ####Début du programme####
     
    mafenetre=Tk()
    mafenetre.title("JEU")
    lab = Label (text = "CLiquez pour commencer")
    lab.pack()
    monbouton= Button(mafenetre,text="quitter",command = mafenetre.quit)
    monbouton.pack()
     
    canevas = Canvas(mafenetre,width=1150,height=997,background="white")
    canevas.pack()
     
    perso = PhotoImage(file = "perso avant le bac.gif")
    balle = canevas.create_image(348,648, image = perso)
     
    #Classe: toplevel 
    class Window(Toplevel):
        def __init__(self, master=None):
            Toplevel.__init__(self, master)
            lab = Label(self, text="""Qui a quatre pattes le matin, deux à midi et trois le soir...Quelle énigme est-ce?
    1-l'épitaphe de diophante
    2_le paradoxe du doublement de jules henri poincarré
    3_l'énigme de webber
    4_l'énigme du sphinx
    """, font = "arial 15")
            lab.pack()
            ent = Entry(self)
            ent.pack()
            ButValider= Button(self,text="valider",command=getResult)
            ButValider.pack()
            button = Button(self, text="fermer", command=self.fermer)
            button.pack()
     
     
    #Entrée dans le bâtiment
    x,y = 348, 648
    dx,dy = -1,0  
    def move():
        global x,y,dx,dy
        x,y = x+dx, y+dy
        if (x < 200) : 
            dx,dy = 0,0
            w = Window()
            def fermer(self):
                self.destroy()
     
        canevas.coords(balle,x,y)
        mafenetre.after(25,move)
     
     
    def pointeur (event):
        x,y = event.x, event.y
        move()
        lab.destroy()
    canevas.bind("<Button-1>", pointeur)

  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,

    Ton erreur est normale l'Entry n'existe que dans l'espace de nom de la classe Window.

    L'espace de nom est une notion primordiale en Python et tu sembles, au vu de ton code, tout en ignorer.

    En premier lieu, mets de l'ordre dans ton code, une disposition commune serait par exemple ceci:
    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
     
    # -*- coding: utf-8 -*-
     
    les imports ...
     
    les CONSTANTES ...
     
    les fonctions qui sont dans l'espace global du programmes
    def pointeur(event):
        ...
     
    def move():
        ...
     
    Ensuite ta classe
    class Window(Toplevel):
        def __init__(self, master=None):
            ...
     
        def getResult(self):
            ...
     
        def fermer(self):
            ...
     
    Et tu termines par la création de ton appli
    mafenetre=Tk()
    ...
    Ne disperse pas tes lignes de part et d'autres de tes fonctions, il ne sert strictement à rien de placer canevas.bind("<Button-1>", pointeur) juste après la fonction pointeur().

    Garde un nommage cohérent de tes objets, pourquoi ButValider et juste après button ?
    Nomme les objets à partir de leur fonction et si tu veux le type de widget dans le nom, mets le en suffixe, par exemple. valid_btn, close_btn

    Tu fais un joyeux mélange de nom définis dans l'espace global, dans une fonction, et encore dans une autre fonction au moyen de l'instruction global

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
     
    x,y = 348, 648
    dx,dy = -1,0  
    def move():
        global x,y,dx,dy
        ...
     
    def pointeur (event):
        x,y = event.x, event.y
        move()
    Quels sont les x, y qui seront traités dans la fonction move() ?
    Dans le doute, on ouvre une console et on teste:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
     
    >>> x, y = "a", "b"
    >>> def foo():
    ...     global x, y
    ...     print x, y
    ... 
    >>> def baz():
    ...     x, y = 1, 2
    ...     foo()
    ... 
    >>> baz()
    a b
    >>>
    C'est raté ...

    Dans ce genre de situation, on préfèrera passer les valeurs à la fonction.
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
     
    def move(x, y):
        ...
     
    def pointeur (event):
        move(event.x, event.y)
    Ensuite, ta classe:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
     
            w = Window()
            def fermer(self):
                self.destroy()
    self n'est pas un mot-clé du language, une espèce de mot magique qui permet de faire des miracles.
    Ce n'est qu'un nom que tu as déclaré dans la classe Window, qui désigne l'instance de la classe elle-même et qui ne peut pas être utilisé ailleurs que dans cette classe.

    La fonction fermer doit se trouver à l'intérieur de la classe.

    Dans cette classe, fais de tes widgets des attributs de cette instance en les précédant de self

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
     
            self.lab = Label(self,...
            self.ent = Entry(self,...
    Les objets eux-même sont préservés parce que tu leur a donné self pour parent mais leur nom (lab, ent, ...) ont une durée de vie limitée à la fonction __init__. Toujours notre espace de nom.
    Ce qui, ensuite, te permetra d'écrire ta fonction getResult (à mettre dans la classe) comme ceci:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
     
        def getResult(self):
            value = self.ent.get()
            ...
            self.ent.delete (0, END)
            ...
    Voilà, yapluca ...

  3. #3
    Membre du Club
    Femme Profil pro
    faussaire
    Inscrit en
    Avril 2014
    Messages
    8
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Âge : 95
    Localisation : France

    Informations professionnelles :
    Activité : faussaire

    Informations forums :
    Inscription : Avril 2014
    Messages : 8
    Par défaut
    Bonsoir, merci pour ce véritable cours très instructif! en effet c'était fouillis!
    Revoici mon code:
    J'ai essayé d'arranger le plus de choses même si il y a certains trucs que je n'ai pas bien compris (comme le " self.ent.delete(0,END)" dont je ne comprend pas bien l'utilité!).

    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
    from tkinter import *
    from math import cos, sin, pi
    from random import randint
     
    #Définitions des variables
    GAGNE = "Bravo!"
    PERDU = "Perdu...
    N = 4
     
    #def pointeur
    def pointeur (event):
        move( event.x, event.y)
        lab.destroy()
     
    #def move
    x = 348
    y = 648
    dx,dy = -1,0  
    def move(x, y): #positions x et y du personnage)
        global x,y,dx,dy
        x,y = x+dx, y+dy
        if (x < 200) : #x correspondant peu ou proue à l'entrée du lycée
            dx,dy = 0,0
            w = Window()
     
        canevas.coords(balle,x,y)
        mafenetre.after(25,move)
     
    #Classe objet: toplevel du sphinx
    class Window(Toplevel):
     
        def __init__(self, master=None):
            Toplevel.__init__(self, master)
            self.lab = Label(self, text="""Qui a quatre pattes le matin, deux à midi et trois le soir...Quelle énigme est-ce?
    1-l'épitaphe de diophante
    2_le paradoxe du doublement de jules henri poincarré
    3_l'énigme de webber
    4_l'énigme du sphinx
    """, font = "arial 15")
            self.lab.pack()
            self.ent = Entry(self)
            self.ent.pack()
            self.But_Valider= Button(self,text="Valider",command = getResult)
            self.But_Valider.pack()
            self.But_Quitter = Button(self, text="Quitter", command = self.fermer)
            self.But_Quitter.pack()
     
         def getResult(self) :
              value = self.ent.get()
              if not value or not value.isdigit():
                   raise ValueError ("Vous devez répondre par un chiffre!")
              n = int(value)
     
              if n== 4:
                   labRes ['text'] = GAGNE
              else:
                   self.labRes ['text'] = PERDU
                   chantier = Tk()
                   excuses = Label (chantier, text = "Dsl, Impossible de continuer")
                   excuses.pack()
                   self.ent.delete(0,END)
     
         def fermer(self):
              self.destroy()
     
    ####Début du programme####
     
    mafenetre=Tk()
    mafenetre.title("Titre du jeu")
    lab = Label (text = "CLiquez pour commencer")
    lab.pack()
    monbouton= Button(mafenetre,text="quitter",command = mafenetre.quit)
    monbouton.pack()
     
    canevas = Canvas(mafenetre,width=1150,height=997,background="white")
    canevas.bind("<Button-1>", pointeur)
    canevas.pack()
    photo = PhotoImage(file ="ville vraie gif.gif")
    item = canevas.create_image(600,450, image = photo)
     
    perso = PhotoImage(file = "perso avant le bac.gif")
    balle = canevas.create_image(348,648, image = perso)
     
     
     
    mafenetre.mainloop()
    mafenetre.destroy()

    J'ai cependant un nouveau message d'erreur concernant l'indentation au niveau de ma fonction move. Tu m'as dis de passer mes valeurs à la fonction. C'est ce que j'ai fais (en tout cas c'est ce que je croyais bon de faire^^) mais il m'affiche: "name'y' is parameter and global". J'ai du mal à cerner le problème, et je ne vois surtout pas pourquoi il focalise sur le y et non sur le x! J'ai essayé de lui mettre directement les valeurs dans la parenthèse, de ne pas donner de valeurs... Aurais-tu une idée de ce qu'il faut faire?

    J'abuse un peu, mais pourrais-tu me signaler ce qu'il faudrait encore corriger si ce que j'ai fais n'est pas suffisant? Désolée, je débute...

    Merci beaucoup!

  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
    Si tu as des problèmes d'indentation, c'est peut être à cause de copier-coller. J'utilise 4 espaces au lieu de tabulation et de plus ce site rajoute une espace en début de toute ligne de code.

    Bref, faut refaire les indentations comme il faut.

    Pour les valeurs de x et y, je n'avais pensé qu'aux coordonnées du pointeur, mais en fait tu as besoin d'une position de départ. Dans ce cas fais le changement de valeur dans la fonction pointeur et si dy ne change jamais tu peux t'en passer.

    Ça donnerait ça:
    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
     
    x = 348
    y = 648
    dx = -1
     
    def pointeur(event):
        global x, y, dx
        x += dx
        move(x, y)
        lab.destroy()
     
    def move(x, y):
        global dx
        if (x < 200) :
            dx = 0
            w = Window()
    Autres choses, dans ta Window tu as un labRes qui sort de nulle part et tu crées encore une nouvelle fenêtre uniquement pour le message final, pas très utile ça, d'autant plus que tu ne peux peut-être pas créer plusieurs fenêtre Tk() en même temps, tu peux aussi bien laisser ce message dans la même fenêtre.

  5. #5
    Membre du Club
    Femme Profil pro
    faussaire
    Inscrit en
    Avril 2014
    Messages
    8
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Âge : 95
    Localisation : France

    Informations professionnelles :
    Activité : faussaire

    Informations forums :
    Inscription : Avril 2014
    Messages : 8
    Par défaut
    Bonjour! Je crois que j'approche du but, j'ai corrigé mes fonctions pointeur et move. Seulement j'ai encore un message d'erreur concernent les argument donnés à move. On en donne 2 il faut donc en mettre 2 partout où on évoque la fonction (c'est à dire dans la fonction pointeur). Sauf que le message d'erreur m'annonce que je n'en ai pas mis. J'ai fait quelques tests, mais ça ne marche tjrs pas. Que faut-il faire?
    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
    def pointeur (event):
        global x, y, dx
        x +=dx
        move(x, y)
        lab.destroy()
     
    #def move
     
    def move(x, y): #positions x et y du personnage
        global dx
        if (x < 200) : #x correspondant peu ou proue à l'entrée du lycée
            dx = 0
            w = Window()
        canevas.coords(balle,x ,y)
        mafenetre.after (25,move)

  6. #6
    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
    Tu peux copier le message d'erreur complet, merci

  7. #7
    Expert éminent
    Homme Profil pro
    Architecte technique retraité
    Inscrit en
    Juin 2008
    Messages
    21 741
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Manche (Basse Normandie)

    Informations professionnelles :
    Activité : Architecte technique retraité
    Secteur : Industrie

    Informations forums :
    Inscription : Juin 2008
    Messages : 21 741
    Par défaut
    Citation Envoyé par polette Voir le message
    Sauf que le message d'erreur m'annonce que je n'en ai pas mis. J'ai fait quelques tests, mais ça ne marche tjrs pas. Que faut-il faire?
    En écrivant:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    def move(x, y): #positions x et y du personnage
        global dx
        if (x < 200) : #x correspondant peu ou proue à l'entrée du lycée
            dx = 0
            w = Window()
        canevas.coords(balle,x ,y)
        mafenetre.after (25,move)
    vous demandez à Tkinter d'appeler "move" dans 25 ms.
    A ce moment là, l'interpréteur Python ralera de ne pas trouver les paramètre (x, y) attendus.
    Passer des paramètres à move n'est pas un problème, il suffirait d'écrire:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
          mafenetre.after (25, lambda: move(x, y))
    Essayez, vous n'allez pas être content du résultat.

    - W
    Architectures post-modernes.
    Python sur DVP c'est aussi des FAQs, des cours et tutoriels

Discussions similaires

  1. problème message d'erreur
    Par zoub0 dans le forum Android
    Réponses: 2
    Dernier message: 29/03/2012, 21h21
  2. [E-07] Problème message d'erreur
    Par law56100 dans le forum Macros et VBA Excel
    Réponses: 1
    Dernier message: 13/03/2009, 16h04
  3. problème message d'erreur avec konqueror
    Par thou92 dans le forum Ubuntu
    Réponses: 0
    Dernier message: 11/01/2008, 10h19
  4. Problème message d'erreur et action sur clic
    Par rangernoir dans le forum Access
    Réponses: 5
    Dernier message: 26/09/2005, 12h10

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