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 :

overrideredirect et events clavier ?


Sujet :

Tkinter Python

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre Expert 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
    Par défaut overrideredirect et events clavier ?
    Bonjour,

    Existe t'il un moyen simple de récupérer les évènements clavier avec overrideredirect ?

    Pour le moment je ne suis arriver qu'a du code comme ceci mais je dois avouer que ce n'est pas terrible.

    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
    #-*- coding: utf-8 -*-
    #
    #
    #
    try:
        import Tkinter
    except:
        import tkinter as Tkinter
    import termios, sys, os
    from time import sleep
     
    class interface(Tkinter.Tk):
        def __init__(self):
            Tkinter.Tk.__init__(self)
            self.geometry("%dx%d+0+0" % (self.winfo_screenwidth(), self.winfo_screenheight()))
            self['bg']='black'
            self.labaffichage = Tkinter.Label(self, bg='white', width=50)
            self.labaffichage.pack()
            self.overrideredirect(1)
     
        def setvalue(self, value):
            self.labaffichage['text']=value
            self.labaffichage.update()
     
    class gestionnaire():
        def __init__(self, view):
            self.view = view()
            self.view.protocol("WM_DELETE_WINDOW", self._intercepte)
            self.view.bind('<1>', self._clicevent)
            self.flag = True
            self.view.update()
            while self.flag == True:
                lettre = self.getkey()
                if lettre.isalpha():
                    self.view.setvalue(lettre)
                elif lettre == '':
                    self.flag = False
     
        def getkey(self):
            TERMIOS = termios
            fd = sys.stdin.fileno()
            old = termios.tcgetattr(fd)
            new = termios.tcgetattr(fd)
            new[3] = new[3] & ~TERMIOS.ICANON & ~TERMIOS.ECHO
            new[6][TERMIOS.VMIN] = 1
            new[6][TERMIOS.VTIME] = 0
            termios.tcsetattr(fd, TERMIOS.TCSANOW, new)
            c = None
            try:
                c = os.read(fd, 1)
            finally:
                termios.tcsetattr(fd, TERMIOS.TCSAFLUSH, old)
            return c
     
        def _intercepte(self, event=None):
            self.flag = False
            self.view.destroy()
     
        def _clicevent(self, event):
            self._intercepte()
     
    if __name__ == '__main__':
        app = gestionnaire(interface)
    Merci d'avance

    Edit:
    J'avais simplifier le code avec un while à la place d'un thread pour la lecture mais comme celui ci est bloquant je rajoute un elif.

  2. #2
    Membre Expert 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
    Par défaut
    C'est pourtant si simple...

    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 -*-
    #
    #
    #
    try:
        import Tkinter
    except:
        import tkinter as Tkinter
     
    class interface(Tkinter.Tk):
        def __init__(self):
            Tkinter.Tk.__init__(self)
            self.geometry("%dx%d+0+0" % (self.winfo_screenwidth(), self.winfo_screenheight()))
            self['bg']='black'
            self.labaffichage = Tkinter.Label(self, bg='white', width=50)
            self.labaffichage.pack()
            self.keyvar = Tkinter.StringVar()
            self.keyvar.trace("w", self.setvalue)
            self.entrycontrol = Tkinter.Entry(self, bg='black', fg='black', bd=0, textvariable=self.keyvar)
            self.entrycontrol.pack()
            self.overrideredirect(1)
     
        def setvalue(self, *args):
            if self.keyvar.get().isalpha():
                self.labaffichage['text']=self.keyvar.get()
                self.labaffichage.update()
            self.keyvar.set('')
     
        def setfocus(self):
    	    self.entrycontrol.focus_set()
     
    class gestionnaire():
        def __init__(self, view):
            self.view = view()
            self.view.protocol("WM_DELETE_WINDOW", self._intercepte)
            self.view.bind('<1>', self._clicevent)
            self.view.bind('<3>', self._intercepte)
            self.view.setfocus()
            self.view.mainloop()
     
        def _intercepte(self, event=None):
            self.view.destroy()
     
        def _clicevent(self, event):
    		self.view.setfocus()
     
    if __name__ == '__main__':
        app = gestionnaire(interface)

  3. #3
    Membre Expert 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
    Par défaut
    Presque... Le code au dessus fonctionne sous Windows Vista mais sous Linux le WM ne donne pas le focus...

    Le code suivant fonctionne sous Linux:
    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
    from Tkinter import *
     
    def SetValue(*args):
        if keyvar.get().isalpha():
            myapp.IsSet(keyvar.get())
        keyvar.set('')
     
    class TestFullScreen:
        def __init__(self):
            self.PleinEcran()
            self.top.overrideredirect(True)
            self.top.deiconify()
     
        def PleinEcran(self):
            self.top = Toplevel()
            self.top['bg']='black'
            self.l = Label(self.top, bg='white', width=50)
            self.l.pack()
            self.top.withdraw()
            self.top.geometry(str(root.winfo_screenwidth())+"x"+str(root.winfo_screenheight())+"+0+0")
            Button(self.top, text='Quitter', command=quit).pack(side=TOP)
     
        def IsSet(self, text):
            self.l['text']=text
     
    root = Tk()
    myapp = TestFullScreen()
    keyvar = StringVar()
    keyvar.trace("w", SetValue)
    e = Entry(root, textvariable=keyvar)
    e.pack()
    e.focus_set()
    root.mainloop()
    Je testerais cela sous Windows cet après midi mais il ne devrais pas avoir de problème puisque le root est juste recouvert par le Toplevel.

    Si vous avez une autre idée.

    Merci d'avance

  4. #4
    Membre Expert 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
    Par défaut
    finally:

    Petite conclusion.

    Soit le style de code universellement proposé sur le web
    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
    #!/usr/bin/env python
    #-*- coding: utf-8 -*-
    #
    #
    try:
        import Tkinter as Tk
    except:
        import tkinter as Tk
    import threading
    import sys
     
    class SetAffichage(threading.Thread):
        def __init__(self):
            threading.Thread.__init__(self)
            self._stopevent = threading.Event()
            self._getch=_Getch()
     
        def run(self):
            while not self._stopevent.isSet():
                _lettre = self._getch()
                if _lettre.isalpha():
                    l['text']=_lettre
     
        def stop(self):
            self._stopevent.set()
     
    class _Getch:
        def __init__(self):
            try:
                self.impl = _GetchUnix()
            except ImportError:
                self.impl = _GetchWindows()
     
        def __call__(self):
            return self.impl()
     
    class _GetchUnix:
        def __init__(self):
            import tty
     
        def __call__(self):
            import tty, termios
            _fd = sys.stdin.fileno()
            _old_settings = termios.tcgetattr(_fd)
            try:
                tty.setraw(sys.stdin.fileno())
                ch = sys.stdin.read(1)
            finally:
                termios.tcsetattr(_fd, termios.TCSADRAIN, _old_settings)
            return ch
     
    class _GetchWindows:
        def __init__(self):
            import msvcrt
     
        def __call__(self):
            import msvcrt
            return msvcrt.getch()
     
    def Intercepte(event=None):
        trhvar.stop()
        root.destroy()
        sys.exit(0)
     
    root = Tk.Tk()
    Tk.Label(root, bg='white', fg='red', text='test fullscreen').pack(pady=10)
    l = Tk.Label(root, bg='white', width=50)
    l.pack(pady=10)
    Tk.Button(root, text='Quitter', command=Intercepte).pack()
    root.geometry("%dx%d+0+0" % (root.winfo_screenwidth(), root.winfo_screenheight()))
    root['bg']='black'
    root.overrideredirect(1)
    trhvar = SetAffichage()
    trhvar.start()
    root.mainloop()
    Deux choses me gènes :
    L'utilisation du thread et la dépendance a l'os (getch).
    Non, je ne dis pas que le thread c'est mauvais. Je pense juste qu'il est possible de s'en passer ici comme cela a été démontré ailler. Mais cela me dépasse
    Pour le getch je n'ai pas regarder comment cela se passe sous Mac.

    Pour ce qui est des codes donnés:
    Le premier code que j'ai donner fonctionne sous Windows mais sous Linux impossible d'avoir le focus après l'overrideredirect, et ce même si le Widget est créé avant pour garder la liaison avec le WM.
    Le second code fonctionne sous Linux mais sous Vista la fenêtre root reste apparente...

    Il est bien sur possible de 'tricher' et de ne pas utiliser l'overrideredirect pour faire du plein écran.
    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
    #!/usr/bin/env python
    #-*- coding: utf-8 -*-
    #
    #
    try:
        import Tkinter as Tk
    except:
        import tkinter as Tk
     
    def ChangeStr(event):
        if event.char.isalpha():
            l['text']=event.char
     
    root = Tk.Tk()
    root.wm_attributes('-topmost', 1, '-fullscreen', 1)
    root['bg']='black'
    Tk.Label(root, bg='white', fg='red', text='test fullscreen').pack(pady=10)
    l = Tk.Label(root, bg='white', width=50)
    l.pack(pady=10)
    root.geometry(str(root.winfo_screenwidth())+'x'+str(root.winfo_screenheight())+'+0+0')
    Tk.Button(root, text='Quitter', command=quit).pack()
    root.bind('<Key>', ChangeStr)
    root.mainloop()
    Mais ce n'est pas le but de la question.
    Reste que cela ouvre une perspective pour le second code donné.
    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
    #!/usr/bin/env python
    #-*- coding: utf-8 -*-
    #
    #
    try:
        import Tkinter as Tk
    except:
        import tkinter as Tk
     
    def SetValue(*args):
        if keyvar.get().isalpha():
            l['text']=keyvar.get()
        keyvar.set('')
     
    root = Tk.Tk()
    root.wm_attributes('-alpha', 0.0)
    top = Tk.Toplevel()
    top['bg']='black'
    l = Tk.Label(top, bg='white', width=50)
    l.pack()
    top.geometry(str(root.winfo_screenwidth())+"x"+str(root.winfo_screenheight())+"+0+0")
    Tk.Button(top, text='Quitter', command=quit).pack()
    keyvar = Tk.StringVar()
    keyvar.trace("w", SetValue)
    e = Tk.Entry(root, textvariable=keyvar)
    e.pack()
    e.focus_set()
    top.overrideredirect(True)
    root.mainloop()
    alpha n'est pas pris en compte sur ma machine de test Linux mais l'overrideredirect place le top au dessu.
    Sous Windows (Machine de test Vista) -alpha est bien pris en compte et root disparait.
    Une 'magouille' en fait.

    Je suis en cours d'inspiration donc si vous avez une piste.

    Edit:
    J'allais oublier. Dans le cadre du thread il est possible de s'en passer en remplacent le mainloop() par le couple while/update mais cela est tellement préjudiciable aux autres events que ça implique une gestion seulement au clavier.
    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
    #!/usr/bin/env python
    #-*- coding: utf-8 -*-
    #
    #
    try:
        import Tkinter as Tk
    except:
        import tkinter as Tk
    import sys
     
    class _Getch:
        def __init__(self):
            try:
                self.impl = _GetchUnix()
            except ImportError:
                self.impl = _GetchWindows()
     
        def __call__(self):
            return self.impl()
     
    class _GetchUnix:
        def __init__(self):
            import tty
     
        def __call__(self):
            import tty, termios
            _fd = sys.stdin.fileno()
            _old_settings = termios.tcgetattr(_fd)
            try:
                tty.setraw(sys.stdin.fileno())
                ch = sys.stdin.read(1)
            finally:
                termios.tcsetattr(_fd, termios.TCSADRAIN, _old_settings)
            return ch
     
    class _GetchWindows:
        def __init__(self):
            import msvcrt
     
        def __call__(self):
            import msvcrt
            return msvcrt.getch()
     
     
    root = Tk.Tk()
    Tk.Label(root, bg='white', fg='red', text='test fullscreen').pack(pady=10)
    l = Tk.Label(root, bg='white', width=50)
    l.pack(pady=10)
    Tk.Label(root, bg='white', fg='red', text='Hit - for exit').pack(pady=10)
    root.geometry("%dx%d+0+0" % (root.winfo_screenwidth(), root.winfo_screenheight()))
    root['bg']='black'
    root.overrideredirect(1)
    root.update()
    isalive = True
    getch=_Getch()
    while isalive:
        lettre = getch()
        if lettre == '-':
            isalive = False
        elif lettre.isalpha():
            l['text']=lettre
            l.update()

Discussions similaires

  1. Capturer les events clavier et souris
    Par Iron Bull dans le forum Interfaces Graphiques en Java
    Réponses: 3
    Dernier message: 08/10/2009, 19h01
  2. comportement clavier curieux jdialog/joptionpane (skip d'event clavier)
    Par r2d2abc dans le forum Agents de placement/Fenêtres
    Réponses: 0
    Dernier message: 11/03/2009, 17h42
  3. stopper les event clavier firefox avec une alert
    Par ReiVon dans le forum Général JavaScript
    Réponses: 11
    Dernier message: 05/08/2008, 16h15
  4. Déplacement en diagonale, par Event clavier
    Par Pimprenelle dans le forum ActionScript 3
    Réponses: 2
    Dernier message: 30/05/2008, 00h37
  5. wxListBox Events Clavier
    Par xolytem dans le forum wxWidgets
    Réponses: 2
    Dernier message: 30/10/2006, 16h10

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