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 :

Débutant : tailles (dynamique) de frames, problèmes d'entry (saisie temps réel + choisir sa largeur)


Sujet :

Tkinter Python

  1. #1
    Membre régulier
    Homme Profil pro
    Etudiant CNAM (DIE20)
    Inscrit en
    Janvier 2010
    Messages
    151
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Etudiant CNAM (DIE20)

    Informations forums :
    Inscription : Janvier 2010
    Messages : 151
    Points : 97
    Points
    97
    Par défaut Débutant : tailles (dynamique) de frames, problèmes d'entry (saisie temps réel + choisir sa largeur)
    Bonjour,

    je fais suite au post résolu situé ici.

    j'ai commencé le python il y a environ 2 semaines (la 1ère semaine consistant essentiellement à lire le swaroop et à feuilleter le swinnen), et actuellement, je découvre tkinter en programmant un logiciel destiné à apprendre les 4 opérations pour ma fille (et les filles des autres que ça intéresserait, et même aux garçons, la licence n'étant pas restrictive sur ce sujet )

    J'ai déjà bien avancé, mais je n'arrive pas à trouver de doc claire et de préférence en français pour fignoler la mise en page :
    - adapter l'intérieur de la fenêtre (y compris la taille des polices si possible) en fonction de sa taille totale : si par exemple on réduit de 50% sa hauteur et sa largeur, il faudrait tout réduire de 50% à l'intérieur
    - pour la saisie prénom et date de naissance, je fais une saisie temps réel de l'entry pour ne pas avoir à taper sur la touche entrée, mais il manque toujours le dernier caractère : comment faire ? actualiser le .get() quand l'utilisateur clique sur l'entry de la saisie principale ??? ça marcherait surement mais je ne trouve pas ça très propre... Y a t'il un évènement du style "on quitte l'entry" qui pourrait déclencher le get() ? cela dit, cette question est plus pour le principe car je pense faire une pop-up pour rentrer prénom et date de naissance et l'afficher ensuite comme label dans la fenêtre principale, ce qui ne nécessiterait pas de get() en temps réel.
    - toujours pas trouvé l'astuce pour la réduction de taille des entry. j'ai essayé sans succès la méthode geometry ainsi que width

    Voici le dernier code en date :

    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
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    116
    117
    118
    119
    120
    121
    122
    123
    124
    125
    126
    127
    128
    129
    130
    131
    132
    133
    134
    135
    136
    137
    138
    139
    140
    141
    142
    143
    144
    145
    146
    147
    148
    149
    150
    151
    152
    153
    154
    155
    156
    157
    158
    159
    160
    161
    162
    163
    164
    165
    166
    167
    168
    169
    170
    171
    172
    173
    174
    175
    176
    177
    178
    179
    180
    181
    182
    183
    184
    185
    186
    187
    188
    189
    190
    191
    192
    193
    194
    195
    196
    197
    198
    199
    200
    201
    202
    203
    204
    205
    206
    207
    208
    209
    210
    211
    212
    213
    214
    215
    216
    217
    218
    219
    220
    221
    222
    223
    224
    225
    226
    227
    228
    229
    230
    231
    232
    233
    234
    #!/usr/bin/python3
    # -*- coding: utf-8 -*-
    # Necessite : python3 et les librairies tkinter / tix
     
    ############################################################
    ### Programme permettant de s'entrainer au calcul mental ###
    ### en générant aléatoirement des opérations simples à   ###
    ### résoudre                                             ###
    ############################################################
     
    # Auteur : Spirzouf ( spirzouf at laposte point net )
    # Date : 26 jan 2010
    # Programme sous licence Creative Commons BY-NC-SA
    # http://creativecommons.org/licenses/by-nc-sa/2.0/fr/
    # UN GRAND MERCI À PauseKawa POUR SON AIDE, SANS LAQUELLE J'AURAIS SUREMENT MIS PLUSIEURS JOURS DE PLUS POUR PROGRAMMER CECI
    # http://www.developpez.net/forums/d867242/autres-langages/python-zope/gui/tkinter/debutant-modifications-dynamiques-fenetre-tkinter/#post4942269
     
    # version de développement.
    # reste à faire :
    # - FAIT ! choix dynamique des intervalles de randomisation
    # - FAIT ! possibilité de faire soustraction / multiplication / division
    # - FAIT ! possibilité de panacher les exercices (addition suivie d'une soustraction, etc..)
    # - apprentissage des tables d'addition, soustraction et multiplication avec base de données donnant pour chaque opération (ex. 5 x 2 = ...)
    # - une note sur les 10 derniers essais afin de favoriser la sortie des opérations pour lesquelles l'élève a le moins bien répondu
    # Y'a encore du boulot !!!
     
    from tkinter import *
    import tkinter.font, tkinter.messagebox, tkinter.tix
    from random import randint
     
    class Application(tkinter.tix.Tk):
        def __init__(self):
            tkinter.tix.Tk.__init__(self)
            # Valeurs par défauts
            # self.mini, self.maxi = 0, 10 # par défaut, les nombres aléatoires seront tirés dans l'intervalle [0,10]
            self.prenom, self.ddn = 'prénom', 'JJ/MM/AAAA'
            # Création des variables du menu
            self.choixAdd, self.choixSous, self.choixMult, self.choixDiv = IntVar(), IntVar(), IntVar(), IntVar()
            self.mini, self.maxi = IntVar(), IntVar()
            # Création et configuration des frames et widgets inclus
            self.miseEnPage()
            # Initialisation des variables du menu
            self.buttonChoixAdd.select()
            self.buttonChoixSous.deselect()
            self.buttonChoixMult.deselect()
            self.buttonChoixDiv.deselect()
            #self.listeMini.entry.insert(0, 0) # par défaut, les nombres aléatoires seront tirés dans l'intervalle [0,10]
            self.listeMaxi.entry.insert(0, 1)
            print(self.listeMini.entry.get() , self.listeMaxi.entry.get())
            # Affichage plein écran
            self.geometry(str(self.winfo_screenwidth())+"x"+str(self.winfo_screenheight())+"+0+0")
            # Création de binds pour enclencher la procédure reponseSaisie lors de l'appuie d'une des 2 touches "entrée"
            # http://www.pythonware.com/library/tkinter/introduction/events-and-bindings.htm
            self.saisie.bind('<Return>', self.reponseSaisie)
            self.saisie.bind('<KP_Enter>', self.reponseSaisie)
            # A FAIRE : bind de validation de la saisie (autoriser uniquement touches 0à9 + sToOpP) 
            self.saisiePrenom.bind('<Key>', self.reponsePrenom)
            self.saisieDDN.bind('<Key>', self.reponseDDN)
            # A FAIRE : binds des Entry du menu
            # Valeurs par défaut et Première initialisation de self.question
            self.initOperation()
     
        def miseEnPage(self): # Création des frames et des widgets
            CouleurFondMenu = 'lightyellow'
            CouleurFondExo = 'lightgreen'
            self.config(bg=CouleurFondMenu)
            # Frames du haut contenant le menu de l'application
            self.menu = Frame(self, width=1920, height=400, bg=CouleurFondMenu)
            self.menu.pack()
            self.menu1 = Frame(self.menu, width=480, height=400, bg=CouleurFondMenu)
            self.menu1.grid(row=1,column=1)
            self.menu2 = Frame(self.menu, width=480, height=400, bg=CouleurFondMenu)
            self.menu2.grid(row=1,column=2)
            self.menu3 = Frame(self.menu, width=480, height=400, bg=CouleurFondMenu)
            self.menu3.grid(row=1,column=3)
            self.menu4 = Frame(self.menu, width=480, height=400, bg=CouleurFondMenu)
            self.menu4.grid(row=1,column=4)
            # Frames du bas contenant la partie exercice et messages de l'application
            self.exo = Frame(self, width=1920, height=600, bg=CouleurFondExo)
            self.exo.pack()
            self.exo1 = Frame(self.exo, width=1920, height=300, bg=CouleurFondExo)
            self.exo1.pack(side=TOP)
            self.exo2 = Frame(self.exo, width=1920, height=300, bg=CouleurFondExo)
            self.exo2.pack()
            self.exo3 = Frame(self.exo, width=1920, height=100, bg=CouleurFondExo)
            self.exo3.pack(side=BOTTOM)
            # Initialisation de la mise en forme tkinter.font (taille des polices)
            tailleMenu = tkinter.font.Font(self)
            tailleMenu.config(size = 20)
            tailleMath = tkinter.font.Font(self)
            tailleMath.config(size = 150)
            tailleMessage = tkinter.font.Font(self)
            tailleMessage.config(size = 40)
            # Initialisation des widgets de la frame menu
            # menu1 ligne 1 : prénom
            self.prenom = Label(self.menu1, text='Mon prénom :')
            self.prenom.config(font = tailleMenu, bg=CouleurFondMenu)
            self.prenom.grid(row=1, column=1, sticky=E)
            self.saisiePrenom = Entry(self.menu1)
            self.saisiePrenom.config(font = tailleMenu, bg=CouleurFondMenu)
            self.saisiePrenom.grid(row=1, column=2)
            # menu1 ligne 2 : date de naissance : servira à créer un profil (associé au prénom)
            # A FAIRE : ComboBoX jour 1-31 - mois en lettres - 19xx/20xx - année 00-99
            self.ddn = Label(self.menu1, text='\nMa date\nde naissance :')
            self.ddn.config(font = tailleMenu, bg=CouleurFondMenu)
            self.ddn.grid(row=2, column=1, sticky=E)
            self.saisieDDN = Entry(self.menu1)
            self.saisieDDN.config(font = tailleMenu, bg=CouleurFondMenu)
            self.saisieDDN.grid(row=2, column=2, sticky=S)
            # menu2 : choix des opérations
            self.buttonChoixAdd = Checkbutton(self.menu2, text='additions (+)', variable=self.choixAdd, selectcolor='red', highlightcolor='green')
            self.buttonChoixAdd.config(font = tailleMenu, bg=CouleurFondMenu)
            self.buttonChoixAdd.grid(column=1, sticky=W)
            self.buttonChoixSous = Checkbutton(self.menu2, text='soustractions (-)', variable=self.choixSous, selectcolor='red', highlightcolor='green')
            self.buttonChoixSous.config(font = tailleMenu, bg=CouleurFondMenu)
            self.buttonChoixSous.grid(column=1, sticky=W)
            self.buttonChoixMult = Checkbutton(self.menu2, text='multiplications (×)', variable=self.choixMult, selectcolor='red', highlightcolor='green')
            self.buttonChoixMult.config(font = tailleMenu, bg=CouleurFondMenu)
            self.buttonChoixMult.grid(column=1, sticky=W)
            self.buttonChoixDiv = Checkbutton(self.menu2, text='divisions (÷)', variable=self.choixDiv, selectcolor='red', highlightcolor='green')
            self.buttonChoixDiv.config(font = tailleMenu, bg=CouleurFondMenu)
            self.buttonChoixDiv.grid(column=1, sticky=W)
            # menu3 (avec 2 nouvelles sous-frames) : A FAIRE binds et évènements
            self.menu31 = Frame(self.menu3) ; self.menu31.pack(side=TOP)
            self.menu32 = Frame(self.menu3) ; self.menu32.pack()
            Label(self.menu31, text='Avec les chiffres', font = tailleMenu, bg=CouleurFondMenu).pack()
            # -> déroulant chiffre self.mini
            Label(self.menu32, text='de', font = tailleMenu, bg=CouleurFondMenu).grid(row=1, column=1)
            self.listeMini = tkinter.tix.ComboBox(self.menu32, editable=1, dropdown=1, variable=self.mini)
            for i in range(0,11):
                self.listeMini.insert(i, i)
            self.listeMini.grid(row=1, column=2)
            # -> déroulant chiffre self.maxi
            Label(self.menu32, text='à', font = tailleMenu, bg=CouleurFondMenu).grid(row=1, column=3)
            self.listeMaxi = tkinter.tix.ComboBox(self.menu32, editable=1, dropdown=1, variable=self.maxi)
            for i in range(0,11):
                self.listeMaxi.insert(i, i)
            self.listeMaxi.grid(row=1, column=4)
            # menu4 : A FAIRE binds et évènements
            Label(self.menu4, text='Faire la table de', font = tailleMenu, bg=CouleurFondMenu).grid(row=1, column=1)
            ChiffreTable= tkinter.tix.IntVar()
            listeChiffreTable = tkinter.tix.ComboBox(self.menu4, editable=1, dropdown=1, variable=ChiffreTable)
            for i in range(0,11):
                listeChiffreTable.insert(i, i)
            listeChiffreTable.grid(row=1, column=2)
            listeChiffreTable.config(bg=CouleurFondMenu)
            Label(self.menu4, text='en', font = tailleMenu, bg=CouleurFondMenu).grid(row=2, column=1)
            TypeTable= tkinter.tix.IntVar()
            listeTypeTable = tkinter.tix.ComboBox(self.menu4, editable=1, dropdown=1, variable=TypeTable)
            listeTypeTable.config(bg=CouleurFondMenu)
            compteur = -1
            for i in ("additions", "soustractions", "multiplication", "divisions"):
                compteur += 1
                listeTypeTable.insert(compteur, i)
            listeTypeTable.grid(row=2, column=2)
            listeTypeTable.entry.delete(0, END) # efface la zone de saisie
            listeTypeTable.entry.insert(0, "additions") # initialise à addition
            listeTypeTable.entry.config(state='readonly')  # zone de saisie en lecture seule
            TypeTable = "additions"
     
            # Initialisation des widgets de la frame exo
            self.title('Additions de chiffres entre 0 et 10')
            self.message = Label(self.exo1)
            self.message.config(font = tailleMessage, text='Ecris ta réponse dans la case jaune', wraplength=1100, bg=CouleurFondExo)
            self.message.grid(row=2, column=1)
            self.question = Label(self.exo2)
            self.question.config(font = tailleMath, bg=CouleurFondExo)
            self.question.grid(row=1, column=1, sticky=W)
            self.saisie = Entry(self.exo2)
            self.saisie.grid(row=1, column=2, sticky=W)
            self.saisie.config(font = tailleMath, bg='lightyellow')
            Label(self.exo3, text="\nPour terminer, écris 'stop' ou cliques sur la croix en haut à droite\n", bg=CouleurFondExo).grid(row=3, column=1)
     
        def initOperation(self): # Procédure d'initialisation de la nouvelle opération à résoudre
            operandes, operandesOK, compteur = ['+', '-', '*', '/'], [], 0
            listeOperations = [self.choixAdd.get(), self.choixSous.get(), self.choixMult.get(), self.choixDiv.get()]
            for i in listeOperations :
                if i == 1:
                    operandesOK.append(operandes[compteur])
                compteur += 1
            operande = operandesOK[randint( 1 , len(operandesOK))-1]
            mini, maxi = int(self.listeMini.entry.get()), int(self.listeMaxi.entry.get())
            mini, maxi = min(mini,maxi), max(mini,maxi) # pour les petits qui voudraient faire les malins !
            a, b = randint(mini,maxi), randint(mini,maxi)
            if operande == '/': 
                a *= b # obtenir un résultat entier pour a/b
                b= max(b,1) # empecher la division par zero
            if operande == '-' : # obtenir a≥b pour les soustractions
                a , b = max(a,b) , min (a,b)
            self.questionText = str('{0} {1} {2}'.format (a,operande,b))
            self.resultat = int(eval(self.questionText))
            if operande == '/':
                self.questionText = str('{0} ÷ {1} = '.format (a,b))
            elif operande == '*':
                self.questionText = str('{0} × {1} = '.format (a,b))
            else:
                self.questionText += ' = '            
            self.question.config(text = self.questionText) # Affiche l'opération à résoudre
            self.saisie.delete(0, END) # Vide l'espace de saisie
            self.saisie.focus_set() # Donne le focus à l'espace de saisie
     
        def reponseSaisie(self, event=None):
            ##### event=None car bind retourne un event et nous n'en avons pas besoin ici...
            ##### ... et nécessaire sinon message d'erreur car deux arguments fournis alors que un seul serait attendu.
            # Affichage de l'opération à effectuer au niveau du Label 'question'
            self.question.config(text = self.questionText)
            # Saisie de la réponse
            reponse = self.saisie.get() # Entry retourne toujours un str (Exception, l'utilisation d'un IntVar()/textvariable par exemple)
            if reponse == 'stop': # va afficher un message d'adieu
                self.message.config(text= "D'accord, à bientot", fg='orange')
                tkinter.messagebox.showinfo('Fini !', "J'espère que tu t'es bien amusé, au revoir et à bientôt.")
                self.quit() # on quitte
            reponse = eval(reponse)
            # http://python.developpez.com/faq/?page=Entry#EntryGet
            # test de la réponse et affichage d'un message adapté au niveau du Label 'message'
            if reponse == self.resultat : # va afficher un message de félicitation avec confirmation du résultat
                self.message.config(text= "Bien joué : {0}{1} !\nOn continue avec :".format(self.questionText, self.resultat), fg='darkgreen')
                self.initOperation() # on lance une nouvelle opération à résoudre
            else: # va afficher un message d'erreur avec le résultat
                self.bell() # bip
                self.message.config(text= "Et NON, ce n'est pas {0} !!!\nLa bonne réponse était {1}{2}".format(reponse, self.questionText, self.resultat), fg='red')
                self.initOperation() # on lance une nouvelle opération à résoudre
     
        def reponsePrenom(self, event=None):
            self.prenom = self.saisiePrenom.get() # Saisie du prénom
            print(self.prenom)
     
        def reponseDDN(self, event=None):
            self.ddn = self.saisieDDN.get() # Saisie de la date de naissance
            print(self.ddn)
     
    app = Application()
    app.mainloop()
    # Tout code après le mainloop est exécuté après la destruction de la fenetre
    Merci d'avances pour vos lumières !

  2. #2
    Membre régulier
    Homme Profil pro
    Etudiant CNAM (DIE20)
    Inscrit en
    Janvier 2010
    Messages
    151
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Etudiant CNAM (DIE20)

    Informations forums :
    Inscription : Janvier 2010
    Messages : 151
    Points : 97
    Points
    97
    Par défaut
    Bonsoir,

    Mon programme s'étoffe,

    - j'ai finalement fait la pop up d'identification au démarrage, mais le mystère reste entier pour le manque du dernier caractère saisi avec GET en temps réel dans un entry : je reste preneur de toute explication concernant ce phénomène

    - j'ai trouvé comment réduire la taille de la fenêtre de saisie de l'ENTRY, c'était tout bêtement le width et je croyais l'avoir déjà testé donc je m'entétais à trouver une solution compliquée, bref... ce point est résolu. Par contre, ça ne marche pas sur les COMBOBOX : une solution ??

    - toujours preneur d'une piste pour l'adaptation dynamique des polices et tailles des frames lors d'un redimensionnement de la fenêtre


    dernier code en date :
    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
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    116
    117
    118
    119
    120
    121
    122
    123
    124
    125
    126
    127
    128
    129
    130
    131
    132
    133
    134
    135
    136
    137
    138
    139
    140
    141
    142
    143
    144
    145
    146
    147
    148
    149
    150
    151
    152
    153
    154
    155
    156
    157
    158
    159
    160
    161
    162
    163
    164
    165
    166
    167
    168
    169
    170
    171
    172
    173
    174
    175
    176
    177
    178
    179
    180
    181
    182
    183
    184
    185
    186
    187
    188
    189
    190
    191
    192
    193
    194
    195
    196
    197
    198
    199
    200
    201
    202
    203
    204
    205
    206
    207
    208
    209
    210
    211
    212
    213
    214
    215
    216
    217
    218
    219
    220
    221
    222
    223
    224
    225
    226
    227
    228
    229
    230
    231
    232
    233
    234
    235
    236
    237
    238
    239
    240
    241
    242
    243
    244
    245
    246
    247
    248
    249
    250
    251
    252
    253
    254
    255
    256
    257
    258
    259
    260
    261
    262
    263
    264
    265
    266
    267
    268
    269
    270
    271
    272
    273
    274
    275
    276
    277
    278
    279
    280
    281
    282
    283
    284
    285
    286
    287
    288
    289
    290
    291
    292
    293
    294
    295
    296
    297
    298
    299
    300
    301
    302
    303
    304
    305
    306
    307
    308
    309
    310
    311
    312
    313
    314
    315
    316
    317
    318
    319
    320
    321
    322
    323
    324
    325
    326
    327
    328
    329
    330
    331
    332
    333
    334
    335
    336
    337
    338
    339
    340
    341
    342
    343
    344
    345
    346
    347
    348
    349
    350
    351
    352
    353
    354
    355
    356
    357
    358
    359
    360
    361
    362
    363
    364
    365
    366
    367
    368
    369
    370
    371
    372
    373
    374
    375
    #!/usr/bin/python3
    # -*- coding: utf-8 -*-
    # Necessite : python3 et les librairies tkinter / tix
     
    ############################################################
    ### Programme permettant de s'entrainer au calcul mental ###
    ### en générant aléatoirement des opérations simples à   ###
    ### résoudre                                             ###
    ############################################################
     
    # Auteur : Spirzouf ( spirzouf at laposte point net )
    # Date : 29 jan 2010
    # Programme sous licence Creative Commons BY-NC-SA
    # http://creativecommons.org/licenses/by-nc-sa/2.0/fr/
    # UN GRAND MERCI À PauseKawa POUR SON AIDE, SANS LAQUELLE J'AURAIS SUREMENT MIS PLUSIEURS JOURS DE PLUS POUR PROGRAMMER CECI
    # http://www.developpez.net/forums/d867242/autres-langages/python-zope/gui/tkinter/debutant-modifications-dynamiques-fenetre-tkinter/#post4942269
     
    # version de développement.
    # reste à faire :
    # - FAIT ! choix dynamique des intervalles de randomisation
    # - FAIT ! possibilité de faire soustraction / multiplication / division
    # - FAIT ! possibilité de panacher les exercices (addition suivie d'une soustraction, etc..)
    # - apprentissage des tables d'addition, soustraction et multiplication avec base de données donnant pour chaque opération (ex. 5 x 2 = ...)
    # - une note sur les 10 derniers essais afin de favoriser la sortie des opérations pour lesquelles l'élève a le moins bien répondu
    # Y'a encore du boulot !!!
     
    from tkinter import *
    import tkinter.font, tkinter.messagebox, tkinter.tix
    from random import randint
     
    class Identification(Tk):
        def __init__(self):
            Tk.__init__(self)
            # prénom
            self.prenom = Label(self, text='Mon prénom :')
            self.prenom.pack()
            self.saisiePrenom = Entry(self)
            self.saisiePrenom.pack()
            # date de naissance : servira à créer un profil (associé au prénom)
            # A FAIRE : ComboBoX jour 1-31 - mois en lettres - 19xx/20xx - année 00-99
            self.ddn = Label(self, text='\nMa date\nde naissance :')
            self.ddn.pack()
            self.saisieDDN = Entry(self)
            self.saisieDDN.pack()
            # bouton de validation 'gogogo'
            self.go = Button(self, text="C'est parti !", command = self.gogogo)
            self.go.pack()
            # le focus s'incrémente de prénom -> DDN -> bouton 'gogogo' à chaque pression de l'une des 2 touches 'entrée'
            self.saisiePrenom.focus_set()
            self.saisiePrenom.bind('<Return>', self.focusDDN)
            self.saisieDDN.bind('<Return>', self.focusGogogo)
            self.go.bind('<Return>', self.gogogo)
            self.saisiePrenom.bind('<KP_Enter>', self.focusDDN)
            self.saisieDDN.bind('<KP_Enter>', self.focusGogogo)
            self.go.bind('<KP_Enter>', self.gogogo)
     
        def focusDDN(self, event=None):
            self.saisieDDN.focus_set()
     
        def focusGogogo(self, event=None):
            self.go.focus_set()
     
        def gogogo(self, event=None):
            # Récupération du prénom et de la date de naissance (ddn) dans des variables globales
            # puis fermeture de cette fen^etre pour laisser place au lancement de l'application
            global prenom, ddn
            prenom = self.saisiePrenom.get() 
            ddn = self.saisieDDN.get()
            #self.quit() # fait bugger Application()
            self.destroy()
     
    class Application(tkinter.tix.Tk):
        def __init__(self):
            tkinter.tix.Tk.__init__(self)
            # Déclaration et initialisation de certaines variables :
            # - variable de mise en page (tailles des polices, couleurs de fond)
            # - déclaration préalable de variable de type IntVar(), utilisés dans les menus
            # - niveau de difficulté par défaut
            self.initialisationVariables()
            # Création des frames et widgets inclus
            self.miseEnPage()
            # Configuration de certains widgets du menu précédemment créés :
            # - checkbox des 4 opérations
            # - combobox des intervalles de nombres pour le tirage aléatoire
            self.initialisationVariablesMenu()
            # Affichage plein écran
            self.geometry(str(self.winfo_screenwidth())+"x"+str(self.winfo_screenheight())+"+0+0")
            # Création des binds
            # -> procédure reponseSaisie lors de l'appuie d'une des 2 touches "entrée"
            self.saisie.bind('<Return>', self.reponseSaisie)
            self.saisie.bind('<KP_Enter>', self.reponseSaisie)
            # -> procédure de modification du niveau de difficulté lors d'un clic gauche sur une étoile
            self.canvasEtoile.bind('<Button-1>', self.changerNiveauEtoile)
            # Initialisation de la première opération à résoudre
            self.initOperation()
     
        def initialisationVariables(self):
            # Initialisation de la mise en forme (taille des polices, couleurs)
            self.couleurFondMenu = 'lightyellow'
            self.couleurFondExo = 'lightgreen'
            self.couleurEtoileActive = 'red'
            self.tailleMenu = tkinter.font.Font(self)
            self.tailleMenu.config(size = 20)
            self.tailleMath = tkinter.font.Font(self)
            self.tailleMath.config(size = 150)
            self.tailleMessage = tkinter.font.Font(self)
            self.tailleMessage.config(size = 40)
            # Création des variables du menu
            self.choixAdd, self.choixSous, self.choixMult, self.choixDiv = IntVar(), IntVar(), IntVar(), IntVar()
            self.mini, self.maxi = IntVar(), IntVar()
            # Niveau de difficulté par défaut
            self.niveau = 2 # par défaut, affichera 2 étoiles au démarrage
            self.typeTable = tkinter.tix.IntVar()
            self.typeTable = "additions"
     
     
        def initialisationVariablesMenu(self):
            # Par défaut, seules des additions sont proposées au lancement du programme (bouton ChoixAdd en position select)
            self.buttonChoixAdd.select()
            self.buttonChoixSous.deselect()
            self.buttonChoixMult.deselect()
            self.buttonChoixDiv.deselect()
            # Par défaut, les nombres aléatoires seront tirés dans l'intervalle [0,10]
            self.listeMaxi.entry.insert(0, 1) # déjà un 0 dans les champs à l'ouverture de l'appli => insertion du 1 pour mettre à 10
     
        def miseEnPage(self): # Création des frames et des widgets
            # pour les messages personnalisés:
            global prenom
            # couleur de fond pour l'application
            self.config(bg=self.couleurFondMenu)
     
            # Frame intercalaire
            Frame(self, height=50).pack()
            # Frames du haut contenant le menu de l'application
            self.menu = LabelFrame(self, width=1920, height=400, bg=self.couleurFondMenu, text='Choisis ton activité ici')
            self.menu.pack()
            self.menu1 = Frame(self.menu, width=480, height=400, bg=self.couleurFondMenu)
            self.menu1.pack(side=LEFT)
            self.menu4 = Frame(self.menu, width=480, height=400, bg=self.couleurFondMenu)
            self.menu4.pack(side=RIGHT)
            self.menu2 = Frame(self.menu, width=480, height=400, bg=self.couleurFondMenu)
            self.menu2.pack()
            self.menu3 = Frame(self.menu, width=480, height=400, bg=self.couleurFondMenu)
            self.menu3.pack()
            # Frame intercalaire
            Frame(self, height=50).pack()
            # Frames du bas contenant la partie 'exercice'
            self.exo = Frame(self, width=1920, height=600, bg=self.couleurFondExo)
            self.exo.pack()
            self.exo1 = Frame(self.exo, width=1920, height=300, bg=self.couleurFondExo)
            self.exo1.pack(side=TOP)
            self.exo2 = Frame(self.exo, width=1920, height=300, bg=self.couleurFondExo)
            self.exo2.pack()
            self.exo3 = Frame(self.exo, width=1920, height=100, bg=self.couleurFondExo)
            self.exo3.pack(side=BOTTOM)
     
            # Création des widgets de la frame menu
     
            # menu1
            # -> message personnalisé
            self.messageMenu1 = Label(self.menu1, text="{0}, {1} ans,\nfait des mathématiques\n\nDifficulté :".format(prenom,'AGE'))
            self.fontMenu(self.messageMenu1)
            self.messageMenu1.pack()
            # A FAIRE : ajouter le choix des exercices : calcul 1 à 4 opération / recherche du complément (par exemple 2 + x = 10) / tables
            # -> étoiles pour réglage de la difficulté
            self.canvasEtoile = Canvas(self.menu1, width=400, height=100, background=self.couleurFondMenu)
            self.canvasEtoile.pack()
            for x in range(0,4):
                self.creerEtoile( 50+x*100, 50, zoom = 5, numero = x+1 )
     
            # menu2 : choix des opérations
            # A FAIRE : menu à destiner à la consigne d'exercice
            self.buttonChoixAdd = Checkbutton(self.menu2, text='additions (+)', variable=self.choixAdd, selectcolor='red', highlightcolor='green')
            self.fontMenu(self.buttonChoixAdd)
            self.buttonChoixAdd.grid(column=1, sticky=W)
            self.buttonChoixSous = Checkbutton(self.menu2, text='soustractions (-)', variable=self.choixSous, selectcolor='red', highlightcolor='green')
            self.fontMenu(self.buttonChoixSous)
            self.buttonChoixSous.grid(column=1, sticky=W)
            self.buttonChoixMult = Checkbutton(self.menu2, text='multiplications (×)', variable=self.choixMult, selectcolor='red', highlightcolor='green')
            self.fontMenu(self.buttonChoixMult)
            self.buttonChoixMult.grid(column=1, sticky=W)
            self.buttonChoixDiv = Checkbutton(self.menu2, text='divisions (÷)', variable=self.choixDiv, selectcolor='red', highlightcolor='green')
            self.fontMenu(self.buttonChoixDiv)
            self.buttonChoixDiv.grid(column=1, sticky=W)
     
            # menu3 (avec 2 nouvelles sous-frames) :
            # A FAIRE : menu à destiner aux choix des paramètres de l'exercie choisis dans menu1
            self.menu31 = Frame(self.menu3) ; self.menu31.pack(side=TOP)
            self.menu32 = Frame(self.menu3) ; self.menu32.pack()
            Label(self.menu31, text='Avec les chiffres', font = self.tailleMenu, bg=self.couleurFondMenu).pack()
            # -> déroulant chiffre self.mini
            Label(self.menu32, text='de', font = self.tailleMenu, bg=self.couleurFondMenu).grid(row=1, column=1)
            self.listeMini = tkinter.tix.ComboBox(self.menu32, editable=1, dropdown=1, variable=self.mini, width=2)
            for i in range(0,11):
                self.listeMini.insert(i, i)
            self.listeMini.grid(row=1, column=2)
            # -> déroulant chiffre self.maxi
            Label(self.menu32, text='à', font = self.tailleMenu, bg=self.couleurFondMenu).grid(row=1, column=3)
            self.listeMaxi = tkinter.tix.ComboBox(self.menu32, editable=1, dropdown=1, variable=self.maxi, width=2)
            for i in range(0,11):
                self.listeMaxi.insert(i, i)
            self.listeMaxi.grid(row=1, column=4)
     
            # menu4 : sera obsolète et donc A SUPPRIMER quand menu 1 à 3 seront finis
            Label(self.menu4, text='Faire la table de', font = self.tailleMenu, bg=self.couleurFondMenu).grid(row=1, column=1)
            ChiffreTable= tkinter.tix.IntVar()
            listeChiffreTable = tkinter.tix.ComboBox(self.menu4, editable=1, dropdown=1, variable=ChiffreTable)
            for i in range(0,11):
                listeChiffreTable.insert(i, i)
            listeChiffreTable.grid(row=1, column=2)
            listeChiffreTable.config(bg=self.couleurFondMenu)
            Label(self.menu4, text='en', font = self.tailleMenu, bg=self.couleurFondMenu).grid(row=2, column=1)
            listeTypeTable = tkinter.tix.ComboBox(self.menu4, editable=1, dropdown=1, variable=self.typeTable)
            listeTypeTable.config(bg=self.couleurFondMenu)
            compteur = -1
            for i in ("additions", "soustractions", "multiplication", "divisions"):
                compteur += 1
                listeTypeTable.insert(compteur, i)
            listeTypeTable.grid(row=2, column=2)
            listeTypeTable.entry.delete(0, END) # efface la zone de saisie
            listeTypeTable.entry.insert(0, "additions") # initialise à addition
            listeTypeTable.entry.config(state='readonly')  # zone de saisie en lecture seule
     
            # Initialisation des widgets de la frame exo
            self.title('Additions de chiffres entre 0 et 10')
            self.message = Label(self.exo1)
            self.message.config(font = self.tailleMessage, text='À toi de jouer {0}!\nÉcris ta réponse dans la case jaune'.format(prenom),
                                                                wraplength=1100, bg=self.couleurFondExo)
            self.message.grid(row=2, column=1)
            self.question = Label(self.exo2)
            self.question.config(font = self.tailleMath, bg=self.couleurFondExo)
            self.question.grid(row=1, column=1, sticky=W)
            self.saisie = Entry(self.exo2, width=3)
            self.saisie.grid(row=1, column=2, sticky=W)
            self.saisie.config(font = self.tailleMath, bg='lightyellow')
            self.espace1 = Label(self.exo2)
            self.espace2 = Label(self.exo2)
            self.espace1.config(font = self.tailleMessage, text='  ', bg=self.couleurFondExo)
            self.espace2.config(font = self.tailleMessage, text='  ', bg=self.couleurFondExo)
            self.espace1.grid(row=1, column=0, sticky=E)
            self.espace2.grid(row=1, column=3, sticky=W)
            Label(self.exo3, text="\nPour terminer, écris 'stop' ou cliques sur la croix en haut à droite\n", bg=self.couleurFondExo).grid(row=3, column=1)
     
        def fontMenu(self,objet):
            objet.config(font = self.tailleMenu, bg=self.couleurFondMenu)
     
        def creerEtoile(self,x,y,zoom,numero):
            # (x,y) sont les coordonnées du centre de l'étoile
            # zoom est le facteur d'agrandissement
            # numero permettra à l'objet d'etre tagué etoile1, 2, 3, 4 et de définir sa couleur en fonction du niveau configuré au démarrage
            if numero <= self.niveau :
                couleur = self.couleurEtoileActive
            else:
                couleur = self.couleurFondMenu
            z0,z6,z1,z2,z5 = zoom*0,zoom*6,zoom*1,zoom*2,zoom*5
            self.canvasEtoile.create_polygon(
                                    x+z0 , y+z6,
                                    x+z1 , y+z2,
                                    x+z5 , y+z5,
                                    x+z2 , y+z1,
                                    x+z6 , y+z0,
                                    x+z2 , y-z1,
                                    x+z5 , y-z5,
                                    x+z1 , y-z2,
                                    x+z0 , y-z6,
                                    x-z1 , y-z2,
                                    x-z5 , y-z5,
                                    x-z2 , y-z1,
                                    x-z6 , y+z0,
                                    x-z2 , y+z1,
                                    x-z5 , y+z5,
                                    x-z1 , y+z2,
                                    fill=couleur, width=2, outline='black', tags=numero, smooth=True, splinesteps=10)
     
        def changerNiveauEtoile(self,event):
            x,y = event.x,event.y
            item = self.canvasEtoile.find_overlapping((x-5),(y-5),(x+5),(y+5))
            etoile = self.canvasEtoile.gettags(item)
            if len(etoile)>0: # lance la procédure que si clic sur un objet taggé (pour le moment, seules les étoiles le sont, mais +/- autres à venir)
                etoile = str(etoile[0])
                if etoile in "0123456789" : # vérifie si le 1er caractère du tag obtenu est bien un chiffre (attribué aux étoiles lors de leur création)
                    etoile = int(etoile)
                    self.niveau = etoile # met à jour le niveau de difficulté
                    i = 2
                    while i <= etoile : # va colorer en 'couleurEtoileActive' les étoiles jusqu'à celle cliquée incluse
                        self.canvasEtoile.itemconfigure(i, fill=self.couleurEtoileActive) 
                        i += 1
                    while i <= 4 : # colore en couleur de fond les suivantes
                        self.canvasEtoile.itemconfigure(i, fill=self.couleurFondMenu) 
                        i += 1
     
        def parametresNiveau(self): # tranformer self.niveau en variable globale pour y avoir accès dès la fenetre identification ?
            # A FAIRE : procedure modifiant les paramètres d'exercices en fonction du niveau
            # si un profil existe, reprend le niveau du profil, sinon, en choisi un en fonction de l'aĝe si dispo
            # Niveau 1 = paramètres par defaut modifiés comme suit :
                #- affichage de dessin à la place des chiffres (par exemples, 5 carottes pour le chiffres 5) (créer un caneva que l'on agrandit,
                #dans lequel lopération sera posée, et un autre canevas pour la réponse ou l'enfant fait apparaitre ou disparaitre le nombre d'objets
                #qu'il souhaite pour répondre à la question
                #- mini et maxi extrêmes bloqués à 1 et 10
                #- empêcher l'activation des multiplications et les divisions
                #- tables désactivées
            # Niveau 2 = paramètres par defaut modifiés comme suit :
                #- mini et maxi extrêmes bloqués à 1 et 10
                #- désactiver les multiplications et les divisions
            # Niveau 3 = paramètres par defaut modifiés comme suit :
                #- soustractions activées
            # Niveau 4 = niveau 3 + :
                #-affichage de opérations en toutes lettre, idem réponse (deux + deux = quatre)
            pass
     
        def initOperation(self): # Procédure d'initialisation de la nouvelle opération à résoudre
            operandes, operandesOK, compteur = ['+', '-', '*', '/'], [], 0
            listeOperations = [self.choixAdd.get(), self.choixSous.get(), self.choixMult.get(), self.choixDiv.get()]
            for i in listeOperations :
                if i == 1:
                    operandesOK.append(operandes[compteur])
                compteur += 1
            operande = operandesOK [ randint(1,len(operandesOK)) -1 ]
            mini, maxi = int(self.listeMini.entry.get()), int(self.listeMaxi.entry.get())
            mini, maxi = min(mini,maxi), max(mini,maxi) # pour les petits qui voudraient faire les malins !
            a, b = randint(mini,maxi), randint(mini,maxi)
            if operande == '/': 
                a *= b # obtenir un résultat entier pour a/b
                b= max(b,1) # empecher la division par zero
            if operande == '-' : # obtenir a≥b pour les soustractions
                a , b = max(a,b) , min (a,b)
            self.questionText = str('{0} {1} {2}'.format (a,operande,b))
            self.resultat = int(eval(self.questionText))
            if operande == '/':
                self.questionText = str('{0} ÷ {1} = '.format (a,b))
            elif operande == '*':
                self.questionText = str('{0} × {1} = '.format (a,b))
            else:
                self.questionText += ' = '            
            self.question.config(text = self.questionText) # Affiche l'opération à résoudre
            self.saisie.delete(0, END) # Vide l'espace de saisie
            self.saisie.focus_set() # Donne le focus à l'espace de saisie
     
        def reponseSaisie(self, event=None):
            ##### event=None car bind retourne un event et nous n'en avons pas besoin ici...
            ##### ... et nécessaire sinon message d'erreur car deux arguments fournis alors que un seul serait attendu.
            # Affichage de l'opération à effectuer au niveau du Label 'question'
            self.question.config(text = self.questionText)
            # Saisie de la réponse
            reponse = self.saisie.get() # Entry retourne toujours un str (Exception, l'utilisation d'un IntVar()/textvariable par exemple)
            if reponse == 'stop': # va afficher un message d'adieu
                self.message.config(text= "D'accord, à bientot", fg='orange')
                tkinter.messagebox.showinfo('Fini !', "J'espère que tu t'es bien amusé, au revoir et à bientôt.")
                self.quit() # on quitte
            reponse = eval(reponse)
            # http://python.developpez.com/faq/?page=Entry#EntryGet
            # test de la réponse et affichage d'un message adapté au niveau du Label 'message'
            if reponse == self.resultat : # va afficher un message de félicitation avec confirmation du résultat
                self.message.config(text= "Bien joué : {0}{1} !\nOn continue avec :".format(self.questionText, self.resultat), fg='darkgreen')
                self.initOperation() # on lance une nouvelle opération à résoudre
            else: # va afficher un message d'erreur avec le résultat
                self.bell() # bip
                self.message.config(text= "Et NON, ce n'est pas {0} !!!\nLa bonne réponse était {1}{2}".format(reponse, self.questionText, self.resultat), fg='red')
                self.initOperation() # on lance une nouvelle opération à résoudre
     
     
     
    ############################
    #### DÉBUT DU PROGRAMME ####
    ############################
     
    # récupérer le prénom et date de naissance
    prenom = ''
    ddn = ''
    identifiant = Identification()
    identifiant.mainloop()
    # lancer l'application proprement dite
    app = Application()
    app.mainloop()
    # Tout code après le mainloop est exécuté après la destruction de la fenetre
    merci d'avance pour vos réponses et bonne soirée / nuit !

  3. #3
    Expert confirmé Avatar de PauseKawa
    Homme Profil pro
    Technicien Help Desk, maintenance, réseau, système et +
    Inscrit en
    Juin 2006
    Messages
    2 725
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Hérault (Languedoc Roussillon)

    Informations professionnelles :
    Activité : Technicien Help Desk, maintenance, réseau, système et +
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Juin 2006
    Messages : 2 725
    Points : 4 005
    Points
    4 005
    Par défaut
    Bonsoir spirzouf,

    Citation Envoyé par spirzouf Voir le message
    - j'ai finalement fait la pop up d'identification
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    identifiant = Identification()
    identifiant.mainloop()
    # lancer l'application proprement dite
    app = Application()
    app.mainloop()
    Pourquoi ne pas utiliser Toplevel avec withdraw() et deiconify() ?. Sur ton 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
    42
    43
    44
    45
    46
    47
    48
     
    # -*- coding:utf-8 -*-
    from Tkinter import *
     
    class monappli(Tk):
        def __init__(self):
            Tk.__init__(self)
            self.geometry(str(self.winfo_screenwidth())+"x"+str(self.winfo_screenheight())+"+0+0")
            self.withdraw()
            self.prenom = StringVar()
            self.ddn = StringVar()
            Label(self, textvariable=self.prenom).pack()
            Label(self, textvariable=self.ddn).pack()
            self.initialise()
     
        def initialise(self):
            self.wisident = Toplevel()
            Label(self.wisident, text='Mon prénom :').pack()
            self.saisiePrenom = Entry(self.wisident)
            self.saisiePrenom.pack()
            Label(self.wisident, text='\nMa date\nde naissance :').pack()
            self.saisieDDN = Entry(self.wisident)
            self.saisieDDN.pack()
            self.go = Button(self.wisident, text="C'est parti !", command = self.gogogo)
            self.go.pack()
            self.saisiePrenom.focus_set()
            self.saisiePrenom.bind('<Return>', self.focusDDN)
            self.saisieDDN.bind('<Return>', self.focusGogogo)
            self.go.bind('<Return>', self.gogogo)
            self.saisiePrenom.bind('<KP_Enter>', self.focusDDN)
            self.saisieDDN.bind('<KP_Enter>', self.focusGogogo)
            self.go.bind('<KP_Enter>', self.gogogo)
     
        def focusDDN(self, event=None):
            self.saisieDDN.focus_set()
     
        def focusGogogo(self, event=None):
            self.go.focus_set()
     
        def gogogo(self, event=None):
            self.prenom.set(self.saisiePrenom.get()) 
            self.ddn.set(self.saisieDDN.get())
            self.deiconify()
            self.wisident.destroy()
     
    if __name__ == "__main__":
        app = monappli()
        app.mainloop()
    Je te laisse voir pour centrer le Toplevel


    Citation Envoyé par spirzouf Voir le message
    Par contre, ça ne marche pas sur les COMBOBOX : une solution ??
    Tu commence avec un mélange tkinter/tix... Sinon
    Citation Envoyé par spirzouf Voir le message
    - j'ai trouvé comment réduire la taille de la fenêtre de saisie de l'ENTRY, c'était tout bêtement le width
    Sinon puisque tu parle de 'plein écran' cela n'en est pas :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
            self.menu = LabelFrame(self, width=1920, height=400, bg=self.couleurFondMenu, text='Choisis ton activité ici')
    width

    @+
    Merci d'utiliser le forum pour les questions techniques.

  4. #4
    Membre régulier
    Homme Profil pro
    Etudiant CNAM (DIE20)
    Inscrit en
    Janvier 2010
    Messages
    151
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Etudiant CNAM (DIE20)

    Informations forums :
    Inscription : Janvier 2010
    Messages : 151
    Points : 97
    Points
    97
    Par défaut
    Salut !

    merci d'avoir pris du temps pour t'intéresser à mon cas.

    pour le toplevel, j'ai effectivement vu que ça existait, mais j'avais voulu aller au plus vite avec ce que je connaissais déjà. Je regarderai attentivement ton code demain pour voir son fonctionnement (ce soir, mes neurones sont un peu fatigués )

    poar contre pour la suite, je sais pas si c'est l'heure, mais j'ai l'impression que tu parles par ellipses et j'avoue ne rien comprendre...
    - tu me suggères d'utiliser width pour les combobox ? si c'est ça, je n'ai pas réussi, peux tu me donner la syntaxe ?)
    - pour le plein écran : je ne comprend vraiment pas comment fonctionne le dimensionnement des frames : quelques soient les valeurs que je mets, ça s'adapte au contenu... Et les tutos que j'ai exploré n'ont pas été suffisamment clair, où alors je suis passé trop vite dessus. Donc les valeurs qui sont là sont simplement des restes d'essai de mise en page

  5. #5
    Expert confirmé Avatar de PauseKawa
    Homme Profil pro
    Technicien Help Desk, maintenance, réseau, système et +
    Inscrit en
    Juin 2006
    Messages
    2 725
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Hérault (Languedoc Roussillon)

    Informations professionnelles :
    Activité : Technicien Help Desk, maintenance, réseau, système et +
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Juin 2006
    Messages : 2 725
    Points : 4 005
    Points
    4 005
    Par défaut
    Bonjour,

    Effectivement rien a faire avec le ComboBox de tix...
    A la limite la taille des font ?

    Sinon, une solution alternative (en cours mais je te donne le 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
    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
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    116
    117
    118
    119
    120
    121
    122
    123
    124
    125
    126
    try: from tkinter import *
    except: from Tkinter import *
     
    # Class MonComboBox
    # ComboBox en pur Tkinter
    #
    # Options:
    # width, height, border, background (bg) , foreground (fg), font, relief, cursor,
    # exportselection, selectbackgroun, selectforeground
    #
    # Methodes:
    # activate(int index) => int
    # curselection() => int
    # delete(objet=["ALL" ou int]
    # start=int
    # end=["END" ou int]
    # focus_set()/focus()
    # get()
    # pack(padx=int, pady=int, fill(X, Y, BOTH), expand=bool, side=LEFT, RIGHT, TOP, BOTTOM, CENTER)
    #
    class MonComboBox:
        listeobjets = []
     
        def activate(self, index):
            self.selection.activate(index)
     
        def curselection(self):
            return map(int, self.selection.curselection())[0]
     
        def delete(self, objet=None, start=None, end=None):
            if objet=='ALL':
                self.selection.delete(0, END)
            elif start == None and end == None:
                self.selection.delete(objet)
            else:
                self.selection.delete(start, end)
     
        def get_focus(self):
            self.zoneselection.get_focus()
     
        def focus(self):
            self.zoneselection.get_focus()
     
        def get(self):
            return self.zoneselection.get()
     
        def pack(self, padx=None, pady=None, fill=None, expand=None, side=None):
            self.cadre.pack(padx=padx, pady=pady, fill=fill, expand=expand, side=side)
     
        def size(self):
            return self.selection.size()
     
        def insert(self, START, objet):
            self.listeobjets.append(objet)
            self.selection.insert(START, objet)
            self.selection.select_set(0)
            self.zoneselection.delete(0, END)
            self.zoneselection.insert(0, self.selection.get(self.selection.curselection()))
     
        def selectionner(self, event):
            def i(event):
                try:
                    self.zoneselection.delete(0, END)
                    self.zoneselection.insert(0, self.selection.get(self.selection.curselection()))
                except:
                    pass
                self.widgetstate()
            self.selection.bind("<ButtonRelease-1>", i)
     
        def widgetstate(self, event=None):
            # True : Visible
            # False : Cache la listbox
            if self.valeur_widget_state == True:
                self.valeur_widget_state = False
                self.listescroll.pack_forget()
                self.selection.pack_forget()
            elif self.valeur_widget_state == False:
                self.valeur_widget_state = True
                self.listescroll.pack(side=RIGHT, fill=Y)
                self.selection.pack(fill=X)
     
        def __init__(self, parent, width=None, border=1, background=None, foreground=None, fg=None, bg=None, font=None, relief=None, cursor=None, exportselection=None, selectbackgroun=None, selectforeground=None, height=None):
            self.cadre = Frame(parent)
            self.zoneselection = Entry(self.cadre, width=None, border=border, background=background, foreground=foreground, fg=fg, bg=bg, font=font, relief=relief, cursor=cursor, exportselection=exportselection, selectbackgroun=selectbackgroun, selectforeground=selectforeground, height=height)
            self.zoneselection.pack(fill=X)
            self.listescroll = Scrollbar(self.cadre)
            self.listescroll.pack(side=RIGHT, fill=Y)
            self.selection = Listbox(self.cadre, yscrollcommand=self.listescroll.set, width=None, border=border, background=background, foreground=foreground, fg=fg, bg=bg, font=font, relief=relief, cursor=cursor, exportselection=exportselection, selectbackgroun=selectbackgroun, selectforeground=selectforeground, height=height)
            self.selection.pack(fill=X)
            self.listescroll.config(command=self.selection.yview)
            self.selection.bind("<ButtonPress-1>", self.selectionner)
            self.zoneselection.bind("<ButtonPress-1>", self.widgetstate)
            # On cache tout
            self.valeur_widget_state = True
            self.widgetstate()
     
    class test(Tk):
        def __init__(self):
            Tk.__init__(self)
            self.geometry(str(self.winfo_screenwidth())+'x'
                +str(self.winfo_screenheight())+'+0+0')
     
            monexplication = """        Tk.__init__(self)
            self.geometry(str(self.winfo_screenwidth())+'x'
                +str(self.winfo_screenheight())+'+0+0')
            self.explication = Text(self, bg='white')
            self.explication.insert(END, monexplication)
            self.explication.pack(side=TOP)
            self.listeMini = MonComboBox(self, width=200, bg='black', fg='white')
            self.listeMini.pack(side=TOP, pady=20)
            for i in range(0,100):
                self.listeMini.insert(i, i)
            Button(self, text='QUIT', command=self.quit).pack(side=TOP, pady=20)"""
     
            self.explication = Text(self, bg='white')
            self.explication.insert(END, monexplication)
            self.explication.pack(side=TOP)
            self.listeMini = MonComboBox(self, width=200, bg='black', fg='white')
            self.listeMini.pack(side=TOP, pady=20)
            for i in range(0,100):
                self.listeMini.insert(i, i)
            Button(self, text='QUIT', command=self.quit).pack(side=TOP, pady=20)
     
    if __name__ == '__main__':
        app = test()
        app.mainloop()
    @+

    Edit:
    C'est basé sur un morceau de code que j'ai trouvé sur la toile il y a un moment mais je n'ai plus la source.
    Donne moi les méthodes du combo de tix que tu souhaite utiliser que je les integres.
    Merci d'utiliser le forum pour les questions techniques.

  6. #6
    Expert confirmé Avatar de PauseKawa
    Homme Profil pro
    Technicien Help Desk, maintenance, réseau, système et +
    Inscrit en
    Juin 2006
    Messages
    2 725
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Hérault (Languedoc Roussillon)

    Informations professionnelles :
    Activité : Technicien Help Desk, maintenance, réseau, système et +
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Juin 2006
    Messages : 2 725
    Points : 4 005
    Points
    4 005
    Par défaut
    Citation Envoyé par spirzouf Voir le message
    mais le mystère reste entier pour le manque du dernier caractère saisi avec GET en temps réel dans un entry : je reste preneur de toute explication concernant ce phénomène
    Ton code fonctionne pour moi. Tu parle bien de celui que tu donne plus haut, celui du 30 à 00h41 ? Ou parle tu d'un validate ?
    Merci d'utiliser le forum pour les questions techniques.

  7. #7
    Membre régulier
    Homme Profil pro
    Etudiant CNAM (DIE20)
    Inscrit en
    Janvier 2010
    Messages
    151
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Etudiant CNAM (DIE20)

    Informations forums :
    Inscription : Janvier 2010
    Messages : 151
    Points : 97
    Points
    97
    Par défaut
    Bonjour

    Citation Envoyé par PauseKawa Voir le message
    Ton code fonctionne pour moi. Tu parle bien de celui que tu donne plus haut, celui du 30 à 00h41 ? Ou parle tu d'un validate ?
    non, le code du 30 fonctionne avec la fenetre 'identification' justement pour contourner le problème.
    c'était le code du 26 ou je faisais une saisie temps réel dans laquelle il manque le dernier caractère.

    le code concerné était le suivant :
    - dans __init__
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
            self.saisiePrenom.bind('<Key>', self.reponsePrenom)
            self.saisieDDN.bind('<Key>', self.reponseDDN)
    - procedures
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
        def reponsePrenom(self, event=None):
            self.prenom = self.saisiePrenom.get() # Saisie du prénom
            print(self.prenom)
     
        def reponseDDN(self, event=None):
            self.ddn = self.saisieDDN.get() # Saisie de la date de naissance
            print(self.ddn)
    C'est basé sur un morceau de code que j'ai trouvé sur la toile il y a un moment mais je n'ai plus la source.
    Donne moi les méthodes du combo de tix que tu souhaite utiliser que je les integres.
    ça a déjà un aspect sympa !
    t'embête pas, cette interface est temporaire, je suis en train de tout refaire, avec des boutons qui prendront des aspects ON/OFF (un peu comme mes étoiles de niveau sur la dernière version) et un sélecteur graphique des chiffres.
    d'ailleurs, je me prends bien la tête à créer une nouvelle classe, et en ce sens, l'exemple que tu m'a donné avec MonComboTix va surement bien m'aider.

  8. #8
    Expert confirmé Avatar de PauseKawa
    Homme Profil pro
    Technicien Help Desk, maintenance, réseau, système et +
    Inscrit en
    Juin 2006
    Messages
    2 725
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Hérault (Languedoc Roussillon)

    Informations professionnelles :
    Activité : Technicien Help Desk, maintenance, réseau, système et +
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Juin 2006
    Messages : 2 725
    Points : 4 005
    Points
    4 005
    Par défaut
    C'est normal alors.

    A chaque touche le bind exécute la procédure.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    self.saisiePrenom.bind('<Key>', self.reponsePrenom)
    Qui modifie la variable self.prenom

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
        def reponsePrenom(self, event=None):
            self.prenom = self.saisiePrenom.get() # Saisie du prénom
            print(self.prenom)
    Il manque donc une tape de touche pour avoir la fin.

    Regarde ce que donne ce code si tu fais entrer a la fin.
    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
     
    from Tkinter import *
     
    class Application(Tk):
        def __init__(self):
            Tk.__init__(self)
            self.geometry(str(self.winfo_screenwidth())+"x"+str(self.winfo_screenheight())+"+0+0")
     
            self.prenom = Label(self, text='Mon prénom :')
            self.prenom.config()
            self.prenom.grid(row=1, column=1, sticky=E)
            self.saisiePrenom = Entry(self)
            self.saisiePrenom.config()
            self.saisiePrenom.grid(row=1, column=2)
            self.saisiePrenom.bind('<Key>', self.reponsePrenom)
     
     
        def reponsePrenom(self, event=None):
            self.prenom = self.saisiePrenom.get()
            print(self.prenom)
     
    app = Application()
    app.mainloop()
    C'est pour valider les infos que tu fais ton bind ? Mis à par la date pour vérification du format (et encore si tu fais trois entry de deux caractères, deux caractères puis quatre caractères avec des IntVar()) je pense qu'il est plus facile de passer par un StringVar()
    Merci d'utiliser le forum pour les questions techniques.

  9. #9
    Membre régulier
    Homme Profil pro
    Etudiant CNAM (DIE20)
    Inscrit en
    Janvier 2010
    Messages
    151
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Etudiant CNAM (DIE20)

    Informations forums :
    Inscription : Janvier 2010
    Messages : 151
    Points : 97
    Points
    97
    Par défaut
    justement, c'est bien ce qui m'embête

    je voulais que ce soit 'user friendly' : en gros rien à valider pour que la chaine soit enregistrer (ce n'était pas une question de validate) Et taper une touche de plus à la fin ne l'est pas : quand le gamin a ecris son nom en entier dans la fenêtre, il va prendre la souris pour aller dans l'autre case sans valider avec ENTREE.

    c'est pour cela que j'ai finalement fait une fenêtre à part qui récupère toute la chaine lors de sa fermeture

    sinon, j'avais pensé à faire valider la saisie quand on utilisait un autre widget, mais je trouvais ça lourd.

  10. #10
    Expert confirmé Avatar de PauseKawa
    Homme Profil pro
    Technicien Help Desk, maintenance, réseau, système et +
    Inscrit en
    Juin 2006
    Messages
    2 725
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Hérault (Languedoc Roussillon)

    Informations professionnelles :
    Activité : Technicien Help Desk, maintenance, réseau, système et +
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Juin 2006
    Messages : 2 725
    Points : 4 005
    Points
    4 005
    Par défaut
    Dans ce cas fais un bind du focusout ou du focus dans les autres zones et une procédure pour ton get.

    Exemple :
    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
     
    #!/usr/bin/env python
    # -*- coding: ISO8859-1 -*-
    #
    #
    from Tkinter import *
     
    class Application(Tk):
        def __init__(self):
            Tk.__init__(self)
     
            self.prenom = Label(self, text='Mon prénom :')
            self.prenom.config()
            self.prenom.grid(row=1, column=1, sticky=E)
            self.saisiePrenom = Entry(self)
            self.saisiePrenom.config()
            self.saisiePrenom.grid(row=1, column=2)
            self.saisiePrenom.bind("<FocusOut>", self.enregistre)
     
            self.ddn = Label(self, text='\nMa date\nde naissance :')
            self.ddn.config()
            self.ddn.grid(row=2, column=1, sticky=E)
            self.saisieDDN = Entry(self)
            self.saisieDDN.config()
            self.saisieDDN.grid(row=2, column=2, sticky=S)
            self.saisieDDN.bind("<FocusOut>", self.enregistre)
     
     
        def enregistre(self, event=None):
            self.prenom = self.saisiePrenom.get()
            self.ddn = self.saisieDDN.get()
            print(self.ddn)
            print(self.prenom)
     
    app = Application()
    app.mainloop()
    Edit : Exemple
    Merci d'utiliser le forum pour les questions techniques.

  11. #11
    Membre régulier
    Homme Profil pro
    Etudiant CNAM (DIE20)
    Inscrit en
    Janvier 2010
    Messages
    151
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Etudiant CNAM (DIE20)

    Informations forums :
    Inscription : Janvier 2010
    Messages : 151
    Points : 97
    Points
    97
    Par défaut
    génial, c'est exactement ce que je voulais faire au début (quand j'étais sur du tkinter sans canvas), mais je ne connaissais pas cet évènement. Merci beaucoup, ça me servira.

    En fait, je prends les choses un peu à l'envers, en découvrant les fonctionnalités au fur et à mesure que je construis le script plutôt que de me taper toutes la listes des fonctions dispo, mais c'est surement comme ça que je retiens le mieux aussi.

    je viens de trouver une traduction française de "Tkinter 8.4 reference: a GUI for Python" de John W. Shipman : je vais pouvoir m'y plonger pour découvrir les multiples options à dispo dans tkinter

  12. #12
    Membre régulier
    Homme Profil pro
    Etudiant CNAM (DIE20)
    Inscrit en
    Janvier 2010
    Messages
    151
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Etudiant CNAM (DIE20)

    Informations forums :
    Inscription : Janvier 2010
    Messages : 151
    Points : 97
    Points
    97
    Par défaut
    J'ai réussi à obtenir une mise en page adaptée (pour les polices, tailles de frames et dessins de canvas) en fonction de la taille de la fenêtre au lancement du programme. Je verrai plus tard pour un resize lors d'un redimensionnement de fenêtre.

    J'ai aussi appliqué la méthode de la toplevel pour la fenêtre d'identification.

    Mon programme à tester est

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

Discussions similaires

  1. [LV 2009] Problème d'acquisition en temps réel
    Par Tite-Phil dans le forum LabVIEW
    Réponses: 3
    Dernier message: 25/06/2010, 17h26
  2. Menu dynamique javascript avec frame
    Par cosycorner dans le forum Général JavaScript
    Réponses: 6
    Dernier message: 07/02/2007, 14h53
  3. [Iframe][Débutant]Iframe et taille dynamique
    Par mavina dans le forum Général JavaScript
    Réponses: 26
    Dernier message: 10/05/2006, 11h15
  4. Réponses: 19
    Dernier message: 26/04/2004, 08h54
  5. [Débutant][Taille BD]Meme vide elle fait 25 Mo
    Par exe dans le forum Débuter
    Réponses: 3
    Dernier message: 18/08/2003, 19h19

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