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 :

Class avec python et Tkinter


Sujet :

Tkinter Python

  1. #1
    Membre habitué
    Homme Profil pro
    Étudiant
    Inscrit en
    Juillet 2016
    Messages
    132
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 26
    Localisation : France, Indre et Loire (Centre)

    Informations professionnelles :
    Activité : Étudiant
    Secteur : Industrie

    Informations forums :
    Inscription : Juillet 2016
    Messages : 132
    Points : 130
    Points
    130
    Par défaut Class avec python et Tkinter
    Bonjour à tous,

    Je commence juste les class avec python, grâce à des tutos sur le net j'ai reussi à en faire une. Mais le principe du self m'echappe toujours un peu ...
    Je voulais aussi savoir si la class que je viens de faire est bien optimisée, car c'est quand même son but de base.

    Code :

    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
    import tkinter as tk
     
    class color_button:
        def __init__(self):
            self.tag = None
        def widgets_selected(self,widget1,widget2):#widget is the selected
            self.disable(widget2)
            if widget1['text']=='yes':
                self.colorize(widget1,"green")
            else :
                self.colorize(widget1,"red")
            return      
        def disable(self,widget):
            widget['state']='disabled'
            return
     
        def colorize(self,widget,color):
            widget['bg']=color
            return
     
    react_button=color_button()        
     
    def action():
        react_button.widgets_selected(bouton1,bouton2)
        Question2=tk.Label(root,text="Quit ?").grid(row=2,column=0)
        bouton3=tk.Button(root,text='yes',command=root.destroy).grid(row=3,column=0)
        bouton4=tk.Button(root,text='no').grid(row=3,column=1)
     
    def action2():
        react_button.widgets_selected(bouton2,bouton1)
        Question2=tk.Label(root,text="Quit ?").grid(row=2,column=0)
        bouton3=tk.Button(root,text='yes',command=root.destroy).grid(row=3,column=0)
        bouton4=tk.Button(root,text='no').grid(row=3,column=1)
     
    root=tk.Tk()
    Question1=tk.Label(root,text='Ca va ?').grid(row=0,column=0)
    bouton1=tk.Button(root,text='yes',command=action)
    bouton1.grid(row=1,column=0)
    bouton2=tk.Button(root,text='no',command=action2)
    bouton2.grid(row=1,column=1)
    root.mainloop()
    Merci d'avance,

    Valentin.

  2. #2
    Expert éminent sénior
    Homme Profil pro
    Architecte technique retraité
    Inscrit en
    Juin 2008
    Messages
    21 281
    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 281
    Points : 36 768
    Points
    36 768
    Par défaut
    Salut,

    Citation Envoyé par StabiloHB Voir le message
    Je voulais aussi savoir si la class que je viens de faire est bien optimisée, car c'est quand même son but de base.
    Je ne vois pas trop ce que vous cherchez à optimiser.

    Quand je lis votre code je vois que vous essayer de créer une relation entre les Button Yes/No plutôt que d'utiliser des Radiobutton qui ont déjà cette relation.
    Côté "class", quand vous débutez vous pouvez vous amuser à en construire partout (i.e. arriver à supprimer tout le code qui n'est pas dans une class). Mais à la base, une class sert à créer des objets qui seront semblable côté attributs/méthodes. Si vous définissez une class pour en utiliser qu'une seule instance, çà ne sert à pas grand chose (sinon pour faire joli mais optimisation s’accommode mal avec "joli").
    Puisqu'une class est un objet, son nom doit être un "nom" et non une action/"un verbe" comme "color_button" qu'il faut essayer de donner aux fonctions/méthodes.
    Dans votre code, la répétition est dans la création d'un Label qui contient une question associé à 2 (Radio)button qui attrapent les réponses.
    Vous pourriez vous amuser à créer une "class" héritant de Frame créant Label et Radiobutton associés ce serait un nouveau widget "composite".

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

  3. #3
    Membre habitué
    Homme Profil pro
    Étudiant
    Inscrit en
    Juillet 2016
    Messages
    132
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 26
    Localisation : France, Indre et Loire (Centre)

    Informations professionnelles :
    Activité : Étudiant
    Secteur : Industrie

    Informations forums :
    Inscription : Juillet 2016
    Messages : 132
    Points : 130
    Points
    130
    Par défaut
    Bonjour,

    Merci de votre réponse.

    C'est pour le coter esthétique que j'utilise des boutons mais je suis d'accord les radio seraient plus simples...
    J'avais déjà pensé à cette idée de creer une frame avec une classe, je pense que j'y arriverai. Mais ce que je ne sais pas comment faire par la suite c'est un bouton Cancel qui ramenerait à l'étape supérieur, car ce sont des questions en cascade. Et avec l'histoire d'une frame par question j'arrive juste a recreer une frame donc rénitialiser toute la question...



    Valentin.

  4. #4
    Expert éminent sénior
    Homme Profil pro
    Architecte technique retraité
    Inscrit en
    Juin 2008
    Messages
    21 281
    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 281
    Points : 36 768
    Points
    36 768
    Par défaut
    Citation Envoyé par StabiloHB Voir le message
    Mais ce que je ne sais pas comment faire par la suite c'est un bouton Cancel qui ramenerait à l'étape supérieur, car ce sont des questions en cascade. Et avec l'histoire d'une frame par question j'arrive juste a recreer une frame donc rénitialiser toute la question...
    Si vous ne postez pas de code... pas facile de comprendre les difficultés que vous rencontrez.

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

  5. #5
    Membre habitué
    Homme Profil pro
    Étudiant
    Inscrit en
    Juillet 2016
    Messages
    132
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 26
    Localisation : France, Indre et Loire (Centre)

    Informations professionnelles :
    Activité : Étudiant
    Secteur : Industrie

    Informations forums :
    Inscription : Juillet 2016
    Messages : 132
    Points : 130
    Points
    130
    Par défaut
    Je voulais pas trop mettre de code car c'est très primitif ... Pour cela que je voudrai me mettre aux class

    Voici un exemple de frame de question :
    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
    import tkinter as tk
     
    def Page1():
            frame_page1=tk.Frame(root)
            frame_page1.grid(row=2,column=0)
            titre_question_1=tk.Label(frame_page1,text='Questions :',font='bold').grid(row=0,sticky='w',columnspan=2,ipadx=3,ipady=3)
            def question_1():
                frame_question_1=tk.Frame(frame_page1)
                frame_question_1.grid(row=1,column=0,sticky='w')
                def Cancel_question_1():
                    frame_question_1.destroy()
                    question_1()
                def question():
                    global organisation_yes_question_1,organisation_no_question_1
                    def answer_no_2():
                        organisation_no_question_12['bg']='red'
                        organisation_yes_question_12['state']='disabled'
                        print('Ah')
                        organisation_Cancel.grid(row=2,column=2)
                    def answer_yes_2():
                        organisation_yes_question_12['bg']='red'
                        organisation_no_question_12['state']='disabled'
                        print("oui c'est vrai qu'il fait mauvais temps")
                        organisation_Cancel.grid(row=2,column=2)
                    def answer_yes_1():
                        organisation_yes_question_1['bg']='green'
                        organisation_no_question_1['state']='disabled'
                        print("ok")
                        organisation_Cancel.grid(row=0,column=2)
                    def answer_no_1():
                        global organisation_yes_question_12,organisation_no_question_12
                        organisation_no_question_1['bg']='red'
                        organisation_yes_question_1['state']='disabled'
                        question_1_question_12=tk.Label(frame_question_1,text='a cause du mauvais temps ?',justify="left").grid(row=2,column=0,sticky='w',ipadx=3,ipady=3)
                        organisation_yes_question_12=tk.Button(frame_question_1,text='yes',command=answer_yes_2)
                        organisation_yes_question_12.grid(row=3,column=0,sticky='w')
                        organisation_no_question_12=tk.Button(frame_question_1,text='no',command=answer_no_2)
                        organisation_no_question_12.grid(row=3,column=1,sticky='w')
                        organisation_Cancel.grid(row=0,column=2)
                    question_1_question_1=tk.Label(frame_question_1,text='Salut, ça va ?',justify="left").grid(row=0,column=0,sticky='w',ipadx=3,ipady=3)
                    organisation_yes_question_1=tk.Button(frame_question_1,text='Yes',command=answer_yes_1)
                    organisation_yes_question_1.grid(row=1,column=0,sticky='w')
                    organisation_no_question_1=tk.Button(frame_question_1,text='No',command=answer_no_1)
                    organisation_no_question_1.grid(row=1,column=1,sticky='w')
                organisation_Cancel=tk.Button(frame_question_1,text='Cancel',command=Cancel_question_1)
                question()
            question_1()
     
    root=tk.Tk()
    Page1()
    root.mainloop()
    Merci pour votre temps.

    Valentin

  6. #6
    Expert éminent sénior
    Homme Profil pro
    Architecte technique retraité
    Inscrit en
    Juin 2008
    Messages
    21 281
    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 281
    Points : 36 768
    Points
    36 768
    Par défaut
    Essayez de visualiser votre code en prenant un peu de recul: vous devriez voir une sorte d'arborescence.
    Problème: vos données ont une structure d'arbre mais vous avez mélangé données et code sans séparer navigation dans l'arbre, opération sur chaque nœud,...
    Peut être que vous devriez commencer avec une structure plus simple genre liste de photo où vous avez deux boutons "next", "prev" pour naviguer et une seule opération "afficher" ?

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

  7. #7
    Membre habitué
    Homme Profil pro
    Étudiant
    Inscrit en
    Juillet 2016
    Messages
    132
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 26
    Localisation : France, Indre et Loire (Centre)

    Informations professionnelles :
    Activité : Étudiant
    Secteur : Industrie

    Informations forums :
    Inscription : Juillet 2016
    Messages : 132
    Points : 130
    Points
    130
    Par défaut
    Bonjour,

    quand vous parlez de données ce sont les print ?
    Je ne devrais pas emboiter les fonctions comme ça, mais plutot faire une fonction pour chaque étage. Comme ça si j'ai besoin de retourner juste avant il suffira d'écraser la Frame pour la réouvrir ?

    Merci pour votre temps

    Valentin.

  8. #8
    Expert éminent sénior
    Homme Profil pro
    Architecte technique retraité
    Inscrit en
    Juin 2008
    Messages
    21 281
    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 281
    Points : 36 768
    Points
    36 768
    Par défaut
    Citation Envoyé par StabiloHB Voir le message
    quand vous parlez de données ce sont les print ?
    Les données sont vos questions/réponses.

    Citation Envoyé par StabiloHB Voir le message
    Je ne devrais pas emboiter les fonctions comme ça, mais plutot faire une fonction pour chaque étage.
    Est ce que vous emboîtez des fonctions ou est-ce que vous calquez le code sur les questions/réponses?
    La question n'est pas "je dois ou pas" mais sur le pourquoi du "emboité" i.e. de cette organisation.

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

  9. #9
    Membre habitué
    Homme Profil pro
    Étudiant
    Inscrit en
    Juillet 2016
    Messages
    132
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 26
    Localisation : France, Indre et Loire (Centre)

    Informations professionnelles :
    Activité : Étudiant
    Secteur : Industrie

    Informations forums :
    Inscription : Juillet 2016
    Messages : 132
    Points : 130
    Points
    130
    Par défaut
    Je suis entrain de calquer les questions/réponses et étudis tous les chemins possibles. Chaque fonction correspond à un chemin finalement. Je ne pense pas que l'arborescence du programme soit mauvaise (quand bien même qu'il soit mal écrit) juste que tkinter ne se prete pas à ce genre de situation pour faire des retours en arrière par exemple. N'est ce pas ?

    Je suis donc entrain d'essayer une autre méthode qui pour l'instant est proche de fonctionner, j'ai utiliser des radioButtons pour simplifier les choses. il suffirait d'avoir une autre fonction que les radiobutton appelle pour changer le i et donc la question posée ensuite.
    Voici le code quand pensez vous ?
    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
    import tkinter as tk
    ### question + bouton oui non
     
    def init():
        liste_question=['ça va ?','a cause du mauvais temps ?']
        creation_question(liste_question)  
        return
     
    def creation_question (liste_question):
        for i in range (len(liste_question)) :
            print(i)
            globals()['frame_question%s' %i]=tk.Frame(root).grid(row=i,column=0)
            globals()['question%s' %i]=tk.Label(globals()['frame_question%s' %i],text=liste_question[i]).grid(row=0,column=0)
            globals()['variable%s'%i] = tk.IntVar()
            globals()['radiobuton_yes_%s'%i]=tk.Radiobutton(globals()['frame_question%s'%i], text="Yes", variable=globals()['variable%s'%i], value=1).grid(row=1,column=0)
            globals()['radiobuton_no_%s'%i]=tk.Radiobutton(globals()['frame_question%s'%i], text="No", variable=globals()['variable%s'%i], value=2).grid(row=1,column=1)
        return
     
    if __name__=='__main__':
        root=tk.Tk()
        init()
        root.mainloop()
    Je vous explique le fond de ma pensée : Il faudrait que si on change de choix (de radiobutton) dans la premiere question la frame de la question suivante se change en fonction de la réponse supérieur. Comme ça plus besoin d'un bouton 'Cancel'. Est ce que vous pensez que je peux faire ça avec des listes ?

    Merci pour votre temps

    Valentin.

  10. #10
    Membre habitué
    Homme Profil pro
    Étudiant
    Inscrit en
    Juillet 2016
    Messages
    132
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 26
    Localisation : France, Indre et Loire (Centre)

    Informations professionnelles :
    Activité : Étudiant
    Secteur : Industrie

    Informations forums :
    Inscription : Juillet 2016
    Messages : 132
    Points : 130
    Points
    130
    Par défaut
    j'ai un peu affiné le truc, petit soucis la frame disparait. J'ai pourtant bien mis à la ligne 'i' qui change en fonction de l'indice dans la liste de question.

    Code :
    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
    import tkinter as tk
    ### question + bouton oui non
     
    def init():
        global i,liste_question
        liste_question=['ça va ?','a cause du mauvais temps ?']
        i=0
        creation_question(liste_question,i)  
        return
     
    def creation_question (liste_question,i):
            tk.Frame(root).grid(row=i,column=0)
            tk.Label(text=liste_question[i]).grid(row=0,column=0)
            v= tk.IntVar()
            tk.Radiobutton(text="Yes", variable=v, value=1,command=changement).grid(row=1,column=0)
            tk.Radiobutton(text="No", variable=v, value=2,command=changement).grid(row=1,column=1)
            root.mainloop()
     
    def changement():
        creation_question(liste_question,i+1)
        return
     
    if __name__=='__main__':
        root=tk.Tk()
        init()
    Merci d'avance.

    Valentin

  11. #11
    Expert éminent sénior
    Homme Profil pro
    Architecte technique retraité
    Inscrit en
    Juin 2008
    Messages
    21 281
    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 281
    Points : 36 768
    Points
    36 768
    Par défaut
    Citation Envoyé par StabiloHB Voir le message
    j'ai un peu affiné le truc, petit soucis la frame disparait. J'ai pourtant bien mis à la ligne 'i' qui change en fonction de l'indice dans la liste de question.
    Je dirais que si vous avez créé une Frame, c'est pour y placer (qu'elle soit "parent") des Label et Radiobutton crées après.

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

  12. #12
    Membre habitué
    Homme Profil pro
    Étudiant
    Inscrit en
    Juillet 2016
    Messages
    132
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 26
    Localisation : France, Indre et Loire (Centre)

    Informations professionnelles :
    Activité : Étudiant
    Secteur : Industrie

    Informations forums :
    Inscription : Juillet 2016
    Messages : 132
    Points : 130
    Points
    130
    Par défaut
    ok y'a du mieux :
    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
    import tkinter as tk
    ### question + bouton oui non
     
    def init():
        global i,liste_question
        liste_question=['ça va ?','a cause du mauvais temps ?']
        i=0
        creation_frame(liste_question,i)
        creation_question(liste_question,i)  
        return
    def creation_frame(liste_question,i):
        for i in range (len(liste_question)):
            globals()['frame%s' % i]=tk.Frame(root)
    def creation_question (liste_question,i):
            globals()['frame%s' % i].grid(row=i,column=0)
            tk.Label(globals()['frame%s' % i],text=liste_question[i]).grid(row=0,column=0)
            v= tk.IntVar()
            tk.Radiobutton(globals()['frame%s' % i],text="Yes", variable=v, value=1,command=changement).grid(row=1,column=0)
            tk.Radiobutton(globals()['frame%s' % i],text="No", variable=v, value=2,command=changement).grid(row=1,column=1)
            root.mainloop()
     
    def changement():
        creation_question(liste_question,i+1)
        return
     
    if __name__=='__main__':
        root=tk.Tk()
        init()
    i keep going !

    Merci pour votre temps,

    Valentin.

  13. #13
    Membre habitué
    Homme Profil pro
    Étudiant
    Inscrit en
    Juillet 2016
    Messages
    132
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 26
    Localisation : France, Indre et Loire (Centre)

    Informations professionnelles :
    Activité : Étudiant
    Secteur : Industrie

    Informations forums :
    Inscription : Juillet 2016
    Messages : 132
    Points : 130
    Points
    130
    Par défaut
    Re,

    je reviens vers vous car je me sens proche du but. J'ai reussi l'enchainement des questions, C'est compact et organisé à mon goût.

    Code :

    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
    import tkinter as tk
    ### question + bouton oui non
     
    def init():
        global i,liste_question
        liste_question=['ça va ?','a cause du mauvais temps ?','il fait beau?']
        i=0
        creation_frame(liste_question,i)
        creation_question(liste_question,i)  
        return
    def creation_frame(liste_question,i):
        for i in range (len(liste_question)):
            globals()['frame%s' % i]=tk.Frame(root)
    def creation_question (liste_question,i):
        globals()['frame%s' % i].grid(row=i,column=0)
        tk.Label(globals()['frame%s' % i],text=liste_question[i]).grid(row=0,column=0)
        globals()['v%s'%i]= tk.IntVar()
        globals()['radio-yes-%s'%i]=tk.Radiobutton(globals()['frame%s' % i],text="Yes", variable=globals()['v%s'%i], value=i+1,command=globals()['changement%s'%i]).grid(row=1,column=0)
        globals()['radio-no-%s'%i]=tk.Radiobutton(globals()['frame%s' % i],text="No", variable=globals()['v%s'%i], value=i+2,command=globals()['changement%s'%i]).grid(row=1,column=1)
     
    def changement0():
        if v0.get()==1 :
            creation_question (liste_question,2)      
        if v0.get()==2:
            creation_question (liste_question,1)
        return
     
    def changement1():
        return
     
    def changement2():
        return
     
    if __name__=='__main__':
        root=tk.Tk()
        init()
    Les fonctions 'changement' sont les noeuds. Il manque juste un détail qui à mon avis n'est pas des moindres... Si on commence par sélectionner 'Yes' à la premiere question, ça fait apparaitre la question 2 correspondante. Mais si on sélectionne ensuite le 'No' je voudrai faire disparaitre la question correspondant au 'Yes' et afficher celle du 'No'.
    Je ne sais pas si j'ai été clair sur l'explication de ma difficulté.

    Merci d'avance.

    Valentin.

  14. #14
    Expert éminent sénior
    Homme Profil pro
    Architecte technique retraité
    Inscrit en
    Juin 2008
    Messages
    21 281
    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 281
    Points : 36 768
    Points
    36 768
    Par défaut
    Citation Envoyé par StabiloHB Voir le message
    Les fonctions 'changement' sont les noeuds. Il manque juste un détail qui à mon avis n'est pas des moindres... Si on commence par sélectionner 'Yes' à la premiere question, ça fait apparaitre la question 2 correspondante. Mais si on sélectionne ensuite le 'No' je voudrai faire disparaitre la question correspondant au 'Yes' et afficher celle du 'No'.
    Je ne sais pas si j'ai été clair sur l'explication de ma difficulté.
    Pour l'instant, il faut simplifier votre code: trop compliqué!

    Essayez de comprendre ce que fait ce code ci:
    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
    import tkinter as tk
     
    def ask_question(text, row):
        f = tk.Frame(root)
        f.grid(row=row, column=0)
        f._v = v = tk.IntVar(f, value=0)
        tk.Label(f, text=text).grid(row=0, column=0)
        b1 = tk.Radiobutton(f, text="Yes", variable=v, value=1,command=root.quit)
        b1.grid(row=1,column=0)
        b2 = tk.Radiobutton(f, text="No", variable=v, value=2,command=root.quit)
        b2.grid(row=1,column=1)
        root.mainloop()
     
        b1['command'] = b2['command'] = ''    # je rend les bouton non clickables...
        return v.get()
     
    root = tk.Tk()
    Q = list('ABCD')
    for ix, text in enumerate(Q):
        n = ask_question(text, ix)
    Je pars toujours d'une liste de questions A, B, C, D mais j'utilise mainloop/quit pour supprimer les callbacks et contrôler l'affichage de la question suivante par une simple boucle for...
    Dans cet exemple il est "inconditionnel" (on affiche toujours la question suivante) mais on récupère la réponse donnée (1 ou 2).

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

  15. #15
    Membre habitué
    Homme Profil pro
    Étudiant
    Inscrit en
    Juillet 2016
    Messages
    132
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 26
    Localisation : France, Indre et Loire (Centre)

    Informations professionnelles :
    Activité : Étudiant
    Secteur : Industrie

    Informations forums :
    Inscription : Juillet 2016
    Messages : 132
    Points : 130
    Points
    130
    Par défaut
    J'ai compris votre code sauf la partie :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    f._v = v = tk.IntVar(f, value=0)
    Je ne comprend pas '._v'
    Chez moi les boutons restent quand meme clickablent. En modifiant le for i, il y a moyen de sauter des questions de la liste j'en suis consciens. Mais puisque les boutons et les frames sont valides qu'un instant, il n'y a pas moyen de faire un retour en arrière je me trompe ?

    Merci pour votre temps,

    Valentin.

  16. #16
    Expert éminent sénior
    Homme Profil pro
    Architecte technique retraité
    Inscrit en
    Juin 2008
    Messages
    21 281
    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 281
    Points : 36 768
    Points
    36 768
    Par défaut
    Citation Envoyé par StabiloHB Voir le message
    Je ne comprend pas '._v'

    Les IntVar (et les variables tkinter en général) sont détruits lorsque l'objet Python est déréférence (i.e. à la sortie de la fonction). Le '._v' est juste un truc pour garder une référence. Plus propre serait sans doute la création d'une classe. Mais ajouter un attribut à la volée est bien plus rapide.

    Citation Envoyé par StabiloHB Voir le message
    Chez moi les boutons restent quand meme clickablent. En modifiant le for i, il y a moyen de sauter des questions de la liste j'en suis consciens. Mais puisque les boutons et les frames sont valides qu'un instant, il n'y a pas moyen de faire un retour en arrière je me trompe ?
    Contrairement aux variables, les widgets (Button, Frame, Label) supportent la sortie de la fonction car tkinter ajoute une référence dans le dictionnaire parent.children. En fait, ils existent tant qu'on ne leur applique pas la méthode .destroy.
    Pour le retour en arrière, ici on a une correspondance forte entre le numéro de la question et la "row". Si on veut revenir en arrière, il faut réfléchir à comment on va bien pouvoir gérer autrement cette association et à comment serait traduit le retour arrière vis à vis de l'utilisateur (on efface la dernière question? on lui permet de ressaisir la réponse?).

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

  17. #17
    Membre habitué
    Homme Profil pro
    Étudiant
    Inscrit en
    Juillet 2016
    Messages
    132
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 26
    Localisation : France, Indre et Loire (Centre)

    Informations professionnelles :
    Activité : Étudiant
    Secteur : Industrie

    Informations forums :
    Inscription : Juillet 2016
    Messages : 132
    Points : 130
    Points
    130
    Par défaut
    Après avoir étudier votre exemple plus en profondeur, j'ai reussi à faire paraître les "noeuds" mais toujours pas le changement de fenêtre si l'on reclic sur un radiobouton en amont...
    J'ai tenté de mettre une fonction clear() qui s'affecterait aux boutons à la place du vide : ''. Mais sans succes..

    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
    import tkinter as tk
     
     
    def ask_question(text, row):
        global v
        f = tk.Frame(root)
        f.grid(row=row, column=0)
        f._v = v = tk.IntVar(f, value=0)
        tk.Label(f, text=text).grid(row=0, column=0)
        b1 = tk.Radiobutton(f, text="Yes", variable=v, value=1,command=root.quit)
        b1.grid(row=1,column=0)
        b2 = tk.Radiobutton(f, text="No", variable=v, value=2,command=root.quit)
        b2.grid(row=1,column=1)
        root.mainloop()
     
        b1['command'] = b2['command'] =''    # je rend les boutons non clickables...
        return v.get()
     
    ##for ix, text in enumerate(Q):
    ##    n = ask_question(text, ix)
    def main():
        i=0
        ask_question(Q[0],i)
        if v.get()==1:
            i=i+1
            ask_question(Q[2],i)
        else :
            i=i+1
            ask_question(Q[1],i)            #Noeuds qui remplacent le for i,v enumerate
        if v.get()==1:
            i=i+1
            ask_question(Q[0],i)
        else :
            i=i+1
            ask_question(Q[3],i)
        return
     
    def clear():
        if v.get==1:
            #Supprimer ici la frame correspondant à ask_question(Q[1],1)
            ask_question(Q[2],1)
        else :
            #Supprimer ici la frame correspondant à ask_question(Q[2],1)
            ask_question(Q[1],1)
     
    if __name__=='__main__':
        Q = ['ça va ?','a cause du mauvais temps ?','il fait beau?','pourquoi alors ?']
        root = tk.Tk()
        main()
    Merci pour votre temps,

    Valentin.

  18. #18
    Expert éminent sénior
    Homme Profil pro
    Architecte technique retraité
    Inscrit en
    Juin 2008
    Messages
    21 281
    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 281
    Points : 36 768
    Points
    36 768
    Par défaut
    Salut,

    Je ne sais pas trop où vous voulez aller.
    Si votre but est d'effacer et re-soumettre les questions suivantes lorsque l'utilisateur change sa réponse à une question déjà posée, peut être que ce code vous donnera des idées.
    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
    import tkinter as tk
     
    frame_clicked = None
     
    def on_select(frame):
        global frame_clicked
     
        frame_clicked = frame
        root.after_idle(root.quit)
     
    def ask_question(text):
     
        frame = tk.Frame(root)
        frame._answer = v = tk.IntVar(frame, value=0)
        tk.Label(frame, text=text, width=30).grid(row=0, column=0)
     
        cmd = lambda: on_select(frame)
        b1 = tk.Radiobutton(frame, text="Yes", variable=v, value='1', command=cmd)
        b1.grid(row=1,column=0)
     
        b2 = tk.Radiobutton(frame, text="No", variable=v, value='2', command=cmd)
        b2.grid(row=1,column=1)
     
        return frame
     
     
     
    if __name__=='__main__':
        Q = ['ça va ?','a cause du mauvais temps ?','il fait beau?','pourquoi alors ?']
        root = tk.Tk()
     
        ix = 0
        frames = []
        while 1:
            frame = ask_question(Q[ix])
            frame.grid(row=ix)
            frames.append(frame)
            root.mainloop()
            row = frames.index(frame_clicked)
            print('index:', ix, 'row clicked:', row, 'answer:', frame_clicked._answer.get())
            if row == ix:
                ix += 1
                if ix == len(Q):
                    break
            else:
                row += 1
                for w in (reversed(frames[row:])):
                    print (w)
                    w.destroy()
                    frames.remove(w)
                ix = row
    - W
    Architectures post-modernes.
    Python sur DVP c'est aussi des FAQs, des cours et tutoriels

  19. #19
    Membre habitué
    Homme Profil pro
    Étudiant
    Inscrit en
    Juillet 2016
    Messages
    132
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 26
    Localisation : France, Indre et Loire (Centre)

    Informations professionnelles :
    Activité : Étudiant
    Secteur : Industrie

    Informations forums :
    Inscription : Juillet 2016
    Messages : 132
    Points : 130
    Points
    130
    Par défaut
    Bonjour,
    Merci pour votre réponse.

    Je n'ai pas saisis l'intégralité de votre code..
    La fonction :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    def on_select(frame):
        global frame_clicked
     
        frame_clicked = frame
        root.after_idle(root.quit)
    Sert à savoir quel frame appartient le boutton qui a été changé ?

    Le fonctionnement de cette m'est aussi obscure :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    if row == ix:
                ix += 1
                if ix == len(Q):
                    break
    et je ne comprend pas les conditions pour que le else se lance à la fin ...


    Sinon pour vous re-expliquer mes attentes par rapport à ca code :

    Où j'en suis :
    J'ai reussi à faire mes questions en cascade c'est à dire :
    Nom : cool.png
Affichages : 977
Taille : 21,8 Ko

    avec :
    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
    def ask_question(text, row):
        global v,f,b1,b2
        f = tk.Frame(root)
        f.grid(row=row, column=0)
        f._v = v = tk.IntVar(f, value=0)
        tk.Label(f, text=text).grid(row=0, column=0)
        b1 = tk.Radiobutton(f, text="Yes", variable=v, value=1,command=root.quit)
        b1.grid(row=1,column=0)
        b2 = tk.Radiobutton(f, text="No", variable=v, value=2,command=root.quit)
        b2.grid(row=1,column=1)
        root.mainloop()
        b1['command'] = b2['command'] =''  
        return v.get(),f
     
    if __name__=='__main__':
        import tkinter as tk
        Q = ['ça va ?','a cause du mauvais temps ?','il fait beau?',"envie d'en parler ?",'il y a du soleil ?','il y a de la pluie ?']
        frame=[]
        i=0
        root = tk.Tk()
        ask_question(Q[0],i)
        frame.append(f)
        if v.get()==1:
            i=i+1
            ask_question(Q[2],i)
            if v.get()==1:
                i=i+1
                ask_question(Q[4],i)
            else :
                i=i+1
                ask_question(Q[5],i)
        else :
            i=i+1
            ask_question(Q[1],i)
            if v.get()==1:
                i=i+1
                ask_question(Q[5],i)
            else :
                i=i+1
                ask_question(Q[3],i)
    Maintenant je voudrai remonter à un etage en supprimant le ou les autres d'en dessous si on change de selection en amont. C'est là où je bloque ...

    Merci pour votre temps,

    Valentin.

  20. #20
    Expert éminent sénior
    Homme Profil pro
    Architecte technique retraité
    Inscrit en
    Juin 2008
    Messages
    21 281
    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 281
    Points : 36 768
    Points
    36 768
    Par défaut
    Citation Envoyé par StabiloHB Voir le message
    Je n'ai pas saisis l'intégralité de votre code..
    La fonction :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    def on_select(frame):
        global frame_clicked
     
        frame_clicked = frame
        root.after_idle(root.quit)
    Sert à savoir quel frame appartient le boutton qui a été changé ?
    Tout à fait: vous posez la question ix et l'utilisateur change la réponse à une des questions déjà posée dans [0..ix-1].
    On récupère l'index de cette frame dans frames et on le compare à celui de la question posée.

    Citation Envoyé par StabiloHB Voir le message
    Le fonctionnement de cette m'est aussi obscure :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    if row == ix:
                ix += 1
                if ix == len(Q):
                    break
    et je ne comprend pas les conditions pour que le else se lance à la fin ...
    On récupère l'index(=row) de cette frame dans frames et on le compare à celui de la question posée(=ix).
    S'il correspond à la question posée, on passe à la question suivante sinon on fait le ménage et on repose la question.


    Citation Envoyé par =StabiloHB Voir le message
    Sinon pour vous re-expliquer mes attentes par rapport à ca code :

    Où j'en suis :
    J'ai reussi à faire mes questions en cascade c'est à dire :
    oui mais, vous avez le même soucis qu'au départ: le code fabrique la structure de données plutôt que d'avoir une structure de données arborescence d'un côté et un code qui se balade dans cet arbre, de l'autre.

    Votre structure de données est:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    Q = ['ça va ?',
             'a cause du mauvais temps ?',
             'il fait beau?',
             "envie d'en parler ?",
             'il y a du soleil ?',
             'il y a de la pluie ?']
    QA = (0, ((1, (4, 5)), (2, (5, 3))))
    Autrement dit vous avez une liste de questions (et leur index).
    QA est l'arbre des (n° de question à poser, (sous arbre de question si Yes, sous arbre de questions si No)).
    Une fois posée la question de niveau N, si l'utilisateur change la réponse à une question antérieure, on doit remonter au niveau correspondant, effacer les réponses suivantes, poser la question correspondant à la réponse. Côté "affichage", le code que je vous ai donné est suffisant : ix sera maintenant le niveau et "row" le niveau auquel vous devez remonter.
    Par contre QA n'est plus une simple liste, descendre ne devrait pas trop poser de problèmes. Pour remonter, il va falloir "enrichir" la chose. Peut être en créant une class Noeud ayant un fils "yes", un fils "no", un père (pour remonter), un niveau (pour savoir ou arrêter de remonter).
    Qu'en pensez vous?

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

+ Répondre à la discussion
Cette discussion est résolue.
Page 1 sur 2 12 DernièreDernière

Discussions similaires

  1. Interface graphique avec python et tkinter
    Par MrTGR57 dans le forum Tkinter
    Réponses: 0
    Dernier message: 23/04/2014, 17h10
  2. Snake avec Python 3.0 et Tkinter
    Par tonykart13 dans le forum Tkinter
    Réponses: 18
    Dernier message: 10/06/2012, 21h55
  3. Commencer avec les classes en Python
    Par Ismatus1 dans le forum Linux
    Réponses: 1
    Dernier message: 16/11/2011, 19h39
  4. La POO avec python Tkinter
    Par alberth dans le forum Tkinter
    Réponses: 2
    Dernier message: 06/05/2009, 14h53

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