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 :

Bouton et modification d'une liste


Sujet :

Tkinter Python

  1. #1
    Nouveau membre du Club
    Homme Profil pro
    Responsable de service informatique
    Inscrit en
    Janvier 2021
    Messages
    44
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 48
    Localisation : France, Moselle (Lorraine)

    Informations professionnelles :
    Activité : Responsable de service informatique

    Informations forums :
    Inscription : Janvier 2021
    Messages : 44
    Points : 28
    Points
    28
    Par défaut Bouton et modification d'une liste
    Bonjour,

    J'ai une question d'ordre général. Dans une classe que j'ai crée, un bouton sert à lancer une méthode. Cette méthode récupère une liste créée par une autre méthode et la modifie (il y a un tirage au sort et le nom tiré au sort est sorti de la liste).

    Chaque fois que je clique sur le bouton, la méthode commence à zéro, ce qui est plutôt normal et donc je n'arrive à sortir qu'un nom de la liste.

    Ma question : j'aimerais un bouton (probablement un autre bouton, car je ne vois pas comment un seul bouton peut lancer la méthode et y rester en boucle) qui modifie la liste comme décrit ci-dessus, mais si je re-clique sur le même bouton, cela reprend la liste modifiée obtenu en fin de méthode et un deuxième nom est supprimé…et ainsi de suite jusqu'à ce que la liste soit vide.

    Un aperçu simplifié du 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
     
    from tkinter import *
    import random
     
    class Tirage(object):
        def __init__(self):
            self.root = Tk()
            Button(self.root, text="Tirer au sort", command = self.tirer).grid(row=2, column=1)
            self.root.mainloop()
     
        def liste_des_mots(self):
            #J'ai coupé cette partie un peu longuette de la méthode car aucun lien avec ma question
            return self.ma_liste
     
        def tirer(self):#cette méthode complète permet de modifier la liste, mais via le bouton ci-dessus, 
    #cela recommence au départ à chaque fois, ce qui est normal
            liste = self.liste_des_mots()
    # ma question correspond à la suite, j'aimerais en faire une boucle contrôlée
    # par un bouton (chaque fois que je clique un nom est tiré au sort et oté de la liste)
            self.resultat = random.choice(liste)
            Label(self.root, text=self.resultat).grid(row=2, column=2)
            liste.remove(self.resultat)
    # C'est là mon problème, comment faire pour que la nouvelle liste soit utilisée pour le tirage suivant 
    #et ce grâce à un bouton (j'arrive à le faire avec un input et une condition mais je veux éviter la console, tout en interface graphique.)
     
     
     
     
    if __name__ == '__main__':
     
        f= Tirage()

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

    Vu le code que vous montrez, ça devrait marcher => le problème est "ailleurs".

    Maintenant, si vous doutez qu'une opération aussi élémentaire sur les listes (choisir un de ses items, le supprimer,...) ne fonctionne pas, c'est que vous n'êtes pas assez familier avec les listes (vous n'êtes pas encore confiant de ce qu'on peut en attendre).

    Qui plus est, ajouter tkinter dans ce genre d'opération "complique" mais faire une fonction qui est activée par une saisie via input sera guère différente.

    En plus ajouter des "class" dans le tableau, c'est juste bon pour vous y perdre.

    Sachez que programmer, c'est juste composer des constructions élémentaires sur des objets basiques (listes, chaînes de caractères,...). Si vous ne maîtrisez pas ces opérations élémentaires et objets de base, ça devient très compliqué....
    Mais c'est plus un soucis dans votre plan de formation (moins vite!!!): à vous de le revoir.

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

  3. #3
    Nouveau membre du Club
    Homme Profil pro
    Responsable de service informatique
    Inscrit en
    Janvier 2021
    Messages
    44
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 48
    Localisation : France, Moselle (Lorraine)

    Informations professionnelles :
    Activité : Responsable de service informatique

    Informations forums :
    Inscription : Janvier 2021
    Messages : 44
    Points : 28
    Points
    28
    Par défaut
    Bonjour,

    J'ai réalisé ce même programme sans classe et sans tkinter et il fonctionne très bien. J'aurais aimé avoir une version avec interface graphique. Le programme en lui-même fonctionne et tire au sort un nouveau nom à chaque clic sur le bouton. Le seul point qui m'embête est que j'aurais aimé supprimer le nom tiré au sort de la liste (pour éviter de tirer le même nom deux fois). Mais comme le bouton est associé au déclenchement de la méthode, celle-ci démarre avec la liste initiale, soit avec la liste complète.

    C'est là que j'ai besoin d'un petit coup de pouce…pour lier un bouton à une boucle sans en sortir à chaque clic.

    PS : J'ai essayé de réécrire le programme avec tkinter mais sans les classes. Et bien au final je trouve cela plus fastidieux, mais il est vrai que cela peut résoudre mon problème.

    PPS : Peut-être qu'une solution est de mettre moins d'éléments dans ma classe. Par exemple faire une classe dont la finalité est de proposer une liste et de traiter cette liste dans une autre classe (ou sans classe).

  4. #4
    Expert éminent sénior
    Homme Profil pro
    Architecte technique retraité
    Inscrit en
    Juin 2008
    Messages
    21 287
    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 287
    Points : 36 776
    Points
    36 776
    Par défaut
    Citation Envoyé par Apoptose Voir le message
    Mais comme le bouton est associé au déclenchement de la méthode, celle-ci démarre avec la liste initiale, soit avec la liste complète.
    La liste avec laquelle travaille la méthode tirer est retournée par la méthode liste_des_mots.

    On ne sait pas ce qu'elle fait (vous ne la montrez pas) mais vu ce que vous racontez, elle semble fabriquer la même liste à chaque appel (ce qui serait logique, non?).

    Pour ce genre de question, je ne peux pas vous aider: c'est juste du manque de rigueur (il en faut pour programmer) et une incapacité à relire/comprendre ce que fait le code que vous avez écrit. Quand vous vous exprimez en français, vous vous attachez à vous relire histoire de vous assurer que ça correspond a ce que vous vouliez raconter et que votre interlocuteur comprendra.

    Avec Python, c'est pareil. Vous devez relire votre code en vous mettant à la place de l'interpréteur pour comprendre ce qu'il va bien pouvoir faire des instructions que vous lui demandez d'exécuter et que ça fera bien ce que vous attendiez.

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

  5. #5
    Nouveau membre du Club
    Homme Profil pro
    Responsable de service informatique
    Inscrit en
    Janvier 2021
    Messages
    44
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 48
    Localisation : France, Moselle (Lorraine)

    Informations professionnelles :
    Activité : Responsable de service informatique

    Informations forums :
    Inscription : Janvier 2021
    Messages : 44
    Points : 28
    Points
    28
    Par défaut
    Je comprends…reprenons donc avec des bases plus saine et le programme complet:

    La liste avec laquelle travaille la méthode tirer est retournée par la méthode liste_des_mots.
    ... elle semble fabriquer la même liste à chaque appel (ce qui serait logique, non?).
    Effectivement, elle fabrique une liste mais pas la même, j'ai plusieurs liste et l'objectif est de choisir une des listes…mais peu importe que ce soit une liste ou l'autre, ce qui m'importe c'est la suite.

    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
     
    from tkinter import *
    import random
     
    class Tirage(object):
        def __init__(self):
            self.root = Tk()
            self.root.geometry('300x100')
            self.root.title('Tirage au sort')
            Label(self.root, text='Choix classe:').grid(row=1, column=1)
            Button(self.root, text="Tirer au sort", command = self.tirer).grid(row=2, column=1)
            self.entree = Entry(self.root, width=14)
            self.entree.grid(row=1, column=2)
     
            self.root.mainloop()
     
        def liste_des_mots(self):
            '''recoit un nom de classe
            cherche le fichier correspondant et extrait une liste'''
            self.groupe = (str(self.entree.get()),'.txt')#définit groupe comme tuple                                              
            le_fichier = ''.join(self.groupe)#définit le_fichier comme str issu du tuple groupe
            d = open(le_fichier, encoding='utf-8')
            mon_texte = d.read()
            self.ma_liste = []
            mon_mot = ''
            for d in range(0, len(mon_texte)):
                if mon_texte[d].isalpha():
                    mon_mot = mon_mot + mon_texte[d]
                    #mon_mot = mon_mot.lower()
                else:
                    if mon_mot not in self.ma_liste and mon_mot !='':
                        self.ma_liste.append(mon_mot)
                    mon_mot = ''
            self.ma_liste.sort()
            return self.ma_liste
     
        def tirer(self):
            liste = self.liste_des_mots()
            choisis = []
            self.resultat = random.choice(liste)
            Label(self.root, text=self.resultat).grid(row=2, column=2)
            choisis.append(self.resultat)
            liste.remove(self.resultat)
            if len(choisis)>5:
                liste = liste + choisis
                choisis=[]
                print(choisis,liste,len(choisis))
     
     
    if __name__ == '__main__':
     
        f= Tirage()
    Comme vous pouvez le voir dans la méthode tirer(). Il y a tirage au sort d'un nom qui est sorti de la liste pour éviter de le tirer à nouveau. Par contre, après 5 tirages, les noms sont replacés dans la liste et peuvent être tirés à nouveau.

    Mais pour que cela fonctionne, il faut que la méthode tirer() reprenne avec la liste otée d'un nom…autrement dit il me faut une boucle. Sans tkinter, c'est assez simple de créer une boucle, mais avec tkinter, j'aimerais associer une boucle avec un bouton et/ou une étiquette (label)

    J'imagine que cela passe par la méthode configure mais j'ai du mal à voir comment la mettre en place. En ce moment, je reprend mon programme avec tkinter mais sans les classes et j'ai le même problème, je n'arrive pas à associer le widget label et button à une boucle.

  6. #6
    Expert éminent sénior
    Homme Profil pro
    Architecte technique retraité
    Inscrit en
    Juin 2008
    Messages
    21 287
    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 287
    Points : 36 776
    Points
    36 776
    Par défaut
    Citation Envoyé par Apoptose Voir le message
    Comme vous pouvez le voir dans la méthode tirer(). Il y a tirage au sort d'un nom qui est sorti de la liste pour éviter de le tirer à nouveau. Par contre, après 5 tirages, les noms sont replacés dans la liste et peuvent être tirés à nouveau.
    Comme choisis est réinitialisé à chaque fois, sa longueur sera toujours inférieure à 5.

    Citation Envoyé par Apoptose Voir le message
    Mais pour que cela fonctionne, il faut que la méthode tirer() reprenne avec la liste otée d'un nom…autrement dit il me faut une boucle.
    Il faut surtout éviter d'appeler liste_des_mots à chaque fois, histoire de ne pas écraser la liste modifiée à l'étape précédente. Pour faire çà, on peut ajouter une condition qui signale si la liste a été initialisée (on utilise alors l'ancienne liste) ou pas (on appelle alors liste_des_mots).

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

  7. #7
    Nouveau membre du Club
    Homme Profil pro
    Responsable de service informatique
    Inscrit en
    Janvier 2021
    Messages
    44
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 48
    Localisation : France, Moselle (Lorraine)

    Informations professionnelles :
    Activité : Responsable de service informatique

    Informations forums :
    Inscription : Janvier 2021
    Messages : 44
    Points : 28
    Points
    28
    Par défaut
    Il faut surtout éviter d'appeler liste_des_mots à chaque fois, histoire de ne pas écraser la liste modifiée à l'étape précédente
    Ok, j'avais compris ce point…mais je ne voyais pas comment éviter de l'appeler alors que j'en ai besoin (au moins une fois)

    Pour faire çà, on peut ajouter une condition qui signale si la liste…
    Bonne idée…mais c'est là où je vois mes limites. Je comprends l'idée, mais concrètement j'ai un problème. Voilà comment je comprends les choses :

    1. la méthode tirer() fonctionne bien la première fois, elle fait ce qu'il faut et modifie une liste (disons new_list)
    2. la fois suivante elle repart avec liste_des_mots…alors que j'aimerais qu'elle utilise new_list.
    3. Ce qui faudrait c'est une condition en début de méthode qui permette d'utiliser new_list à la place de liste_de_mots
    4. Mais pour utiliser new_list, il faut la "sortir" (par un return, j'imagine) pour la réutiliser dans la condition au tour suivant

    Et là je bloque…est-ce que mon point 4 a du sens et si oui comment le mettre en place ?

    5. Autre façon de voir les choses :
    Je dois sortir liste_des_mots de la méthode et faire en sorte que la liste utilisée par la méthode soit une des deux listes selon les besoins, donc ajouter un attribut à la méthode avec quelque chose du type :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    def tirer(self, une_liste)
    Mais je suis tout aussi perdu dans cette situation.

    La question qui me taraude est : Est-ce que mes points 4 et 5 sont un début de solution, j'ai compris le truc mais il me manque la technique…où suis-je complètement à coté de la plaque ?

  8. #8
    Expert éminent sénior
    Homme Profil pro
    Architecte technique retraité
    Inscrit en
    Juin 2008
    Messages
    21 287
    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 287
    Points : 36 776
    Points
    36 776
    Par défaut
    Citation Envoyé par Apoptose Voir le message
    Bonne idée…mais c'est là où je vois mes limites. Je comprends l'idée, mais concrètement j'ai un problème.
    A la base, çà ressemble à:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    def tirer(self):
         if condition:
            liste = self.liste_des_mots()
         else:
            liste = self.ma_liste
         ...
    Si condition est un simple drapeau réalisé par l'attribut premier_appel (à créer initialisé à True):
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    def tirer(self):
         if self.premier_appel:
            liste = self.liste_des_mots()
         else:
            liste = self.ma_liste
            self.premier_appel = False.
         ...
    Problème: que se passe-t-il lorsque l'utilisateur met à jour l'Entry (pour choisir un autre fichier)?

    Citation Envoyé par Apoptose Voir le message
    Voilà comment je comprends les choses :
    Vous devez programmer avec ce que Python permet de faire. C'est un jeu de construction mentale. Si vous n'arrivez pas à penser avec Python pour réaliser quelque chose et que vous partez à imaginer ce qui n'est pas, vous n'êtes pas sorti d'affaire.
    Et apprendre à penser avec Python s'apprend en faisant les exercices proposés dans les tutos. (qui sont corrigés) avant de se lancer dans de petits projets où tout devient vite insurmontable faute de repères et manque de savoir-faire.

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

  9. #9
    Nouveau membre du Club
    Homme Profil pro
    Responsable de service informatique
    Inscrit en
    Janvier 2021
    Messages
    44
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 48
    Localisation : France, Moselle (Lorraine)

    Informations professionnelles :
    Activité : Responsable de service informatique

    Informations forums :
    Inscription : Janvier 2021
    Messages : 44
    Points : 28
    Points
    28
    Par défaut
    Merci pour ces informations, je vais tenter les petits exercices afin de consolider les bases tout en continuant à apprendre de nouvelles chose.

    Je pense que cela peut être un bon moyen d'apprendre de faire chaque petit programme en double exemplaire, avec et sans POO…je dois avouer que j'ai pris goût aux classes au point d'avoir même un peu de mal à revenir en arrière (d'où l'idée de faire les deux à la fois)

    Concernant le programme, j'ai enfin réussi à faire quelque chose en modifiant la méthode ainsi :

    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
     
     def tirer(self):
            if self.premier_appel:
                liste = self.liste_des_mots()
                self.premier_appel = False
            else:
                liste = self.ma_liste
                self.premier_appel = False
     
     
            self.resultat = random.choice(liste)
            Label(self.root, text=self.resultat).grid(row=2, column=2)
            self.choisis.append(self.resultat)
            liste.remove(self.resultat)
            if len(self.choisis)>5:
                liste = liste + self.choisis
                self.choisis=[]
                self.ma_liste=liste
    Quelque remarques pour voir si j'ai bon :
    1. Dans def __init__, j'ai rajouté un self.premier_appel et self.choisis…j'ai donc remplacer ma variable choisis par self.choisis
    Si je comprends bien choisis est une variable locale qui reste dans la méthode alors que self.choisis permet de l'utiliser en dehors de la méthode tirer.

    2. J'ai ajouter ligne 5 self.premier_appel = False, car dans le cas contraire ça ne fonctionnait pas.
    Était ce volontaire pour me tester ou il y avait une méthode plus propre pour que le drapeau self.premier_appel passe à False après utilisation ?

    3. En fin de méthode, j'ai ajouté self.ma_liste = liste mais j'imagine que j'aurais pu le remplacer par un self.premier_appel = True. L'objectif étant de reprendre avec la liste complète. C'est peut-être même plus propre avec cette deuxième option en faisant cela
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
     
           if len(self.choisis)>5:
                self.choisis=[]
                self.premier_appel=True
    Problème: que se passe-t-il lorsque l'utilisateur met à jour l'Entry (pour choisir un autre fichier)?
    Pour ce point, c'est un autre défi…pour le moment, comme je suis le seul utilisateur (c'est un peu plus qu'un petit programme pour apprendre, je compte bien l'utiliser), ça ira, d'autant que dans la pratique, je ne passerai pas d'une liste à l'autre.

    Quoiqu'il en soit, merci pour ton aide et ta patience.

  10. #10
    Expert éminent sénior
    Homme Profil pro
    Architecte technique retraité
    Inscrit en
    Juin 2008
    Messages
    21 287
    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 287
    Points : 36 776
    Points
    36 776
    Par défaut
    Citation Envoyé par Apoptose Voir le message
    je dois avouer que j'ai pris goût aux classes au point d'avoir même un peu de mal à revenir en arrière (d'où l'idée de faire les deux à la fois)
    Vous ne maîtriserez pas les "class" sans avoir appris à maîtriser les fonctions.

    Après, c'est vous qui allez ramer à vouloir faire gribouille avec des constructions tordues: vous allez juste prendre de mauvaises habitudes dont il vous sera difficile de vous débarrasser plus tard.

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

  11. #11
    Nouveau membre du Club
    Homme Profil pro
    Responsable de service informatique
    Inscrit en
    Janvier 2021
    Messages
    44
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 48
    Localisation : France, Moselle (Lorraine)

    Informations professionnelles :
    Activité : Responsable de service informatique

    Informations forums :
    Inscription : Janvier 2021
    Messages : 44
    Points : 28
    Points
    28
    Par défaut
    Citation Envoyé par wiztricks Voir le message
    Vous ne maîtriserez pas les "class" sans avoir appris à maîtriser les fonctions.
    C'est bien pour cela que je vais aussi reprendre mon apprentissage sur les fonctions avant d'aller plus loin avec les classes

Discussions similaires

  1. Réponses: 3
    Dernier message: 31/01/2008, 16h42
  2. modification d'une liste chainée
    Par bibi182 dans le forum Langage
    Réponses: 3
    Dernier message: 03/11/2007, 17h49
  3. Réponses: 1
    Dernier message: 16/10/2007, 22h36
  4. modification d'une liste déroulante
    Par julio02200 dans le forum Access
    Réponses: 32
    Dernier message: 23/06/2006, 15h50
  5. Réactiver un bouton sur afterMaj d'une liste !
    Par samlepiratepaddy dans le forum Access
    Réponses: 5
    Dernier message: 12/09/2005, 13h20

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