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 :

bind ne répond pas


Sujet :

Tkinter Python

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre averti
    Homme Profil pro
    retraité
    Inscrit en
    Août 2013
    Messages
    28
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : retraité
    Secteur : Enseignement

    Informations forums :
    Inscription : Août 2013
    Messages : 28
    Par défaut bind ne répond pas
    Bonsoir

    Dans ce programme rudimentaire qui fonctionne bien avec des clics de souris,
    au premier clic s'affiche une fenêtre popup, au second se fermme cette fenêtre.

    Après beaucoup d'essais je n'arrive pas à lier les boutons avec un return sur le clavier.

    Merci de m'éclairer.

    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
    #! /usr/bin/env python
    # -*- coding:Utf-8 -*-
     
     
    from tkinter import *
     
     
    class interface:
     
        def __init__(self):
     
            #self.nbAleatoire = random.choice(range(1,101))
            self.parent=root
     
            self.bouton=Button(self.parent,bg="beige",text="Clic ou Enter pour afficher une fenêtre pop-up",command=self.affichage)
            self.bouton.place(relx=0.3,rely=0.5)
            self.bouton.bind("<Return>",self.affichage)
     
     
        def affichage(self):    
     
            fen1 =FenPopUp("lightblue")
            fen1.affiche("Essai de fenêtre popup")
     
     
     
    class FenPopUp(Toplevel):
        "Fenêtre satellite (modale) contenant un simple canevas"
        def __init__(self,couleur="beige"):
            Toplevel.__init__(self)
            self.geometry("400x200")    # "500x400+100+240" permettrait de décaler l'affichage
            self.overrideredirect(0)            # => si paramètre 1 fenêtre sans bordure ni bandeau
            self.transient(self.master)         # => fenêtre 'modale'
            self.configure(bg=couleur)
     
            self.bouton=Button(self,text="Clic ou Enter pour fermer", command=self.destroy,bg="lightyellow")
            self.bouton.place(width=200,height=30,relx=0.3,rely=0.6)
            self.bouton.bind("<Return>", self.destroy)   # Return pour fermer cette fenetre popup  
            self.bouton.bind("<KP_Enter>", self.destroy)   # Return du clavier numerique 
     
        def affiche(self,messagetransmis):
     
            Label(self,text=messagetransmis,bg="lightgreen").place(width=300,height=30,relx=0.1,rely=0.4)
     
    if __name__ == "__main__":
     
        root = Tk() 
        myapp = interface()
        root.geometry("600x400")
        root.mainloop()

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

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

    Informations forums :
    Inscription : Juin 2008
    Messages : 21 741
    Par défaut
    Salut,

    Votre code est bien complique pour démontrer ce que vous voulez.
    A la base, les widgets "attrapent" les entrées 'clavier' *SI* ils ont le "focus". De nombreux widgets héritent du focus lorsque la souris se positionne ou qu'on clique "dessus". Un Button est un widget "a part": il est suppose déclencher une action lorsqu'on clique dessus sans changer le "focus".

    Jouez avec le code suivant:
    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
    import tkinter as tk
     
    def on_key(event):
        print ('widget', event.widget, 'key', event.keysym, event.keycode)
     
    app = tk.Tk()
     
    btn = tk.Button(app,text='clic', name='btn')
    btn['command'] = lambda: print('focus on:', app.focus_get())
    btn.pack()
     
    tk.Button(text='set_focus', command=btn.focus_set).pack()
     
    btn.bind('<KeyPress>', on_key)
    app.bind('<KeyPress>', on_key)
     
    app.mainloop()
    Ca affiche 2 buttons: "clic" et "set_focus".
    Les entrées clavier déclenchent "on_key".
    Lorsqu'on clique sur "clic", ca affiche le widget qui a le focus.

    Tant qu'on n'a pas clique sur "set_focus", le focus est sur "app" et les entrées clavier sont attrapées par le 2nd "bind" (app.bin).
    "set_focus" donne le focus a "clic", les entrees clavier déclenchent les 2 on_key.

    Surprenant non?

    Si l’idée est d'afficher 2 buttons, genre: Cancel, OK avec un OK par défaut qui accepte un "Return" pour fermer la boite de dialogue,...
    Le "Return" pourrait être attrape par la Toplevel qui "sort" si la saisie est correcte (il y a une validation a faire et traduire OK par défaut en "montrant" la boite OK différemment de la boite "Cancel".
    => comme l'etat de la boite de dialogue est geree "plus haut" qu'au niveau des Button, pas besoin de faire un "bind" specifique dessus. Ils restent Button et tout le monde est content.

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

  3. #3
    Membre averti
    Homme Profil pro
    retraité
    Inscrit en
    Août 2013
    Messages
    28
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : retraité
    Secteur : Enseignement

    Informations forums :
    Inscription : Août 2013
    Messages : 28
    Par défaut
    Merci beaucoup pour votre réponse rapide et éclairante.

    D'ordinaire pour passer un court message dans tkinter j'utilise messagebox et je clique sur OK , mais je n'ai jamais trouvé comment lier le OK à une touche clavier. C'est pourquoi j'ai voulu créer moi-meme ma fenêtre pop-up afin de la gérer personnellement.

    Je vais approfondir vos explications, mais à court terme j'ai déjà solutionné mon problème même si ce n'est pas très propre.

    Dans la première fenêtre j'ai ajouté :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    self.bouton.focus_set()
    pour imposer le focus sur ce bouton et de ce fait j'ai ajouté event dans l'appel de la fenêtre pop-up
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    def affichage(self,event):
    Dans la seconde fenêtre j'ai de même imposé le focus sur le bouton
    mais au lieu d'appeler directement self.destroy j'ai du l' insérer dans une fonction d'o^le code modifié ci-dessous

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
         self.bouton.place(width=200,height=30,relx=0.3,rely=0.6)
            self.bouton.focus_set()                    # AJOUT
            self.bouton.bind("<Return>", self.truc)   # MODIFIE
            self.bouton.bind("<KP_Enter>", self.truc)   # MODIFIE
     
        def truc( self,event):       # AJOUT  
     
            self.destroy()           # AJOUT
    Je me répète, ce n'est pas très propre cela fonctionne dans un cadre restreint comme celui-ci, aussi vais-je étudier vos suggestions pour
    coder plus proprement notamment dans le cas de fenêtres comportant plusieurs widgets.

    J'attends un peu pour marquer la discussion comme résolue afin de proposer quelques chose de plus clair qui puisse être utile à d'autres.

    Encore merci.

  4. #4
    Membre averti
    Homme Profil pro
    retraité
    Inscrit en
    Août 2013
    Messages
    28
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : retraité
    Secteur : Enseignement

    Informations forums :
    Inscription : Août 2013
    Messages : 28
    Par défaut
    Je précise : c'est grâce à vos explications que j'ai déjà partiellement solutionné le problème.

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

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

    Informations forums :
    Inscription : Juin 2008
    Messages : 21 741
    Par défaut
    Salut,
    Je me suis contente de vous expliquer "focus" vs. Button.
    Pour ce qui est de boites de dialogue "custom", vous n’êtes pas le premier, des tutos et des solutions prêtes a l'emploi et adaptables existent déjà.
    Vous pouvez farfouiller sur le Wiki Tkinter, sur le Tkinter boot d'effbot...
    Le tuto/example d'effbot devrait répondre a votre besoin.

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

  6. #6
    Membre averti
    Homme Profil pro
    retraité
    Inscrit en
    Août 2013
    Messages
    28
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : retraité
    Secteur : Enseignement

    Informations forums :
    Inscription : Août 2013
    Messages : 28
    Par défaut
    Bonjour wiztricks,

    J'ai mis en oeuvre vos techniques. C'est beaucoup plus joli et plus universel.

    Il me reste deux problèmes que je n'ai pas encore pu solutionner :

    Je n'arrive pas à fermer la fenêtre toplevel, je ne sais quelle commande affecter, c'est pourquoi j'ai mis pass.

    Par ailleurs je n'ai pas réussi à utiliser le nom du bouton pour filtrer dans le test dans la procédure onkey d'où la ligne mise en remarque.

    Ci-dessous le code et d'avance merci. mais rien d'urgent. Profitez bien de ces fêtes de fin d'année.

    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
    #! /usr/bin/env python
    # -*- coding:Utf-8 -*-
     
     
    from tkinter import *
     
    def on_key(event):
        print(event.widget)
        print ( event.keysym, event.keycode)
       # if  (event.keysym is "f" ) and (event.widget is ".boutonppal"):
        if  (event.keysym is "f" or event.keysym is "g" ) :
            fen1 =FenPopUp("lightblue")
     
        if  (event.keysym is "h" or event.keysym is "j" ) :
            pass
     
     
     
    class interface:
     
        def __init__(self):
     
            self.parent=root
            self.bouton=Button(self.parent,bg="beige",text="Appuyez sur f ou g pour voir une fenêtre pop-up",name="boutonppal",command=self.affichage)
            self.bouton.place(relx=0.3,rely=0.5)
            self.bouton.focus_set()                       
     
            self.bouton.bind('<KeyPress>', on_key)
     
        def affichage(self):      
     
            fen1 =FenPopUp("lightblue")
     
     
    class FenPopUp(Toplevel):
        "Fenêtre satellite (modale) contenant un simple canevas"
        def __init__(self,couleur="beige"):
            Toplevel.__init__(self)
            self.geometry("400x200")    # "500x400+100+240" permettrait de décaler l'affichage
            self.overrideredirect(0)            # => si paramètre 1 fenêtre sans bordure ni bandeau
            self.transient(self.master)         # => fenêtre 'modale'
            self.configure(bg=couleur)
     
            self.bouton=Button(self,text="Cliquez ici ou Appuyez sur h ou j pour fermer", command=self.destroy,bg="lightyellow")
            self.bouton.place(width=300,height=30,relx=0.1,rely=0.6)
            self.bouton.focus_set()                    
     
            self.bouton.bind('<KeyPress>', on_key)
     
     
    if __name__ == "__main__":
     
        root = Tk() 
        myapp = interface()
        root.geometry("600x400")
        root.mainloop()

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

Discussions similaires

  1. htpasswd ne répond pas ce que je veux
    Par lodan dans le forum Apache
    Réponses: 8
    Dernier message: 09/09/2006, 06h58
  2. [VB.NET]Form qui ne répond pas
    Par Pocel dans le forum Windows Forms
    Réponses: 5
    Dernier message: 17/07/2006, 10h42
  3. [c#]fênetre ne répond pas
    Par le_ben dans le forum Windows Forms
    Réponses: 3
    Dernier message: 22/03/2006, 13h26
  4. [TOMCAT] Tomcat ne répond pas au bout de quelques jours
    Par Bartuk dans le forum Tomcat et TomEE
    Réponses: 7
    Dernier message: 02/03/2006, 17h38

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