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

PyQt Python Discussion :

detecter le focus d'une gui [QtGui]


Sujet :

PyQt Python

  1. #1
    Nouveau membre du Club
    Inscrit en
    Août 2008
    Messages
    41
    Détails du profil
    Informations forums :
    Inscription : Août 2008
    Messages : 41
    Points : 28
    Points
    28
    Par défaut detecter le focus d'une gui
    Bonjour,

    Je cherche un moyen de detecter si l'ui est active ou non (self.hasFocus()) au cours de l'execution. Je cherche à executer une function quand l'utilisateur clique sur une autre fenetre (l'ui devient donc inactive) et quand l'utilisateur revient sur l'ui.

    Une idée ?
    Merci

  2. #2
    Expert éminent
    Avatar de tyrtamos
    Homme Profil pro
    Retraité
    Inscrit en
    Décembre 2007
    Messages
    4 461
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Var (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Retraité

    Informations forums :
    Inscription : Décembre 2007
    Messages : 4 461
    Points : 9 248
    Points
    9 248
    Billets dans le blog
    6
    Par défaut
    Bonjour,

    Dans une application multifenêtre, on peut savoir si l'une des fenêtres est active avec:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    if QtGui.QApplication.activeWindow()==variabledinstancedelafenetre:
        ...
    Cela marche, même si aucun widget à l'intérieur de la fenêtre n'accepte un focus (une image par exemple).

    Mais dans le cas contraire, on peut, dans la fenêtre à tester, mettre à jour une variable en surchargeant la méthode "eventFilter" et en testant si le focus est 'in' ou 'out'. Si tu es intéressé, je peux proposer du code.
    Un expert est une personne qui a fait toutes les erreurs qui peuvent être faites, dans un domaine étroit... (Niels Bohr)
    Mes recettes python: http://www.jpvweb.com

  3. #3
    Nouveau membre du Club
    Inscrit en
    Août 2008
    Messages
    41
    Détails du profil
    Informations forums :
    Inscription : Août 2008
    Messages : 41
    Points : 28
    Points
    28
    Par défaut
    Merci,

    voici mon code, tout simple juste pour tester ce cas là :

    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
     
    #!/usr/bin/python
    # -*- coding: utf-8 -*-
     
    import sys
    from PyQt4 import QtGui
     
     
    class Mywindow(QtGui.QWidget):
     
        def __init__(self):
            QtGui.QSystemTrayIcon.__init__(self)
            self.initUI()
     
        def initUI(self):
     
            QtGui.QToolTip.setFont(QtGui.QFont('SansSerif', 10))
            btn = QtGui.QPushButton('Button', self)
            btn.resize(btn.sizeHint())
            btn.move(10, 10)
            self.setGeometry(300, 300, 250, 150)
     
            #self.connect(self._infocus)
            self.show()
     
        def _infocus(self):
            if self.hasFocus():
                #do focus stuff
            else:
                #do no focus stuff
     
    def main():
        app = QtGui.QApplication(sys.argv)
        win = Mywindow()
        sys.exit(app.exec_())
     
    if __name__ == '__main__':
        main()

  4. #4
    Expert éminent

    Homme Profil pro
    Inscrit en
    Octobre 2008
    Messages
    4 300
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Belgique

    Informations forums :
    Inscription : Octobre 2008
    Messages : 4 300
    Points : 6 780
    Points
    6 780
    Par défaut
    Salut,

    Les widgets ont des méthodes focusInEvent() et focusOutEvent().

    Il faut fixer les règles de focus avec setFocusPolicy()

    Reprenant ton 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
     
    # -*- coding: utf-8 -*-
     
    import sys
     
    from PyQt4 import QtCore, QtGui
     
    class Mywindow(QtGui.QWidget):
     
        def __init__(self):
            super(Mywindow, self).__init__()
            btn = QtGui.QPushButton('Button', self)
            btn.resize(btn.sizeHint())
            btn.move(10, 10)
            self.setGeometry(300, 300, 250, 150)
     
            self.setFocusPolicy(QtCore.Qt.StrongFocus)
            self.show()
     
        def focusInEvent(self, event):
            print 'Widget has focus:', self.hasFocus()
            print 'Reason:', event.reason()
     
        def focusOutEvent(self, event):
            print 'Widget has focus:', self.hasFocus()
            print 'Reason:', event.reason()
     
     
    def main():
        app = QtGui.QApplication(sys.argv)
        win = Mywindow()
        sys.exit(app.exec_())
     
    if __name__ == '__main__':
        main()

    Edit: rajouté la raison de l'event.
    http://www.riverbankcomputing.co.uk/...cusPolicy-enum

  5. #5
    Expert éminent
    Avatar de tyrtamos
    Homme Profil pro
    Retraité
    Inscrit en
    Décembre 2007
    Messages
    4 461
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Var (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Retraité

    Informations forums :
    Inscription : Décembre 2007
    Messages : 4 461
    Points : 9 248
    Points
    9 248
    Billets dans le blog
    6
    Par défaut
    Bonjour,

    Il faut clarifier le problème à résoudre!

    Dans une fenêtre qui possède plusieurs widgets susceptibles de recevoir le focus, il y a une différence entre une fenêtre "active" (comme quand on clique sur son bandeau) et une fenêtre qui a le focus.

    Dans ce dernier cas, quand la fenêtre devient active, l'un des widgets "attrape" le focus, et les méthodes focusInEvent et focusOutEvent de la fenêtre ne sont jamais exécutées. Ou il faudrait sous-classer tous les widgets intérieurs et établir un lien entre toutes ces mêmes méthodes.

    En surchargeant la méthode eventFilter de la fenêtre, c'est plus simple parce qu'on peut tester dedans tous les widgets pour savoir qui a le focus "in" ou "out" sans avoir à sous-classer ces widgets.

    En fait, avec le code fourni par kiby56, je ne comprends pas à quel moment ni pourquoi il souhaite poser la question. Si c'est en cliquant sur le bouton, on connait déjà la réponse: la fenêtre sera forcément active!

    @kiby56: donne plus d'explications stp!
    Un expert est une personne qui a fait toutes les erreurs qui peuvent être faites, dans un domaine étroit... (Niels Bohr)
    Mes recettes python: http://www.jpvweb.com

  6. #6
    Expert éminent

    Homme Profil pro
    Inscrit en
    Octobre 2008
    Messages
    4 300
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Belgique

    Informations forums :
    Inscription : Octobre 2008
    Messages : 4 300
    Points : 6 780
    Points
    6 780
    Par défaut
    Ben, moi j'ai compris que c'était sur la fenêtre que le focus l'intéressait.

    ... Je cherche à executer une function quand l'utilisateur clique sur une autre fenetre (l'ui devient donc inactive) et quand l'utilisateur revient sur l'ui
    Evidemment quand on clique sur le bouton de ladite fenêtre celle-ci perd le focus au profit du bouton. Ce qui apparaît dans mon exemple.

  7. #7
    Expert éminent
    Avatar de tyrtamos
    Homme Profil pro
    Retraité
    Inscrit en
    Décembre 2007
    Messages
    4 461
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Var (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Retraité

    Informations forums :
    Inscription : Décembre 2007
    Messages : 4 461
    Points : 9 248
    Points
    9 248
    Billets dans le blog
    6
    Par défaut
    @VinsS

    Oui, mais avec ton exemple, quand on rend la fenêtre active (alors qu'elle ne l'était pas) en cliquant directement sur son bouton, la méthode focusInEvent n'est pas exécutée.

    De même, quand on rend la fenêtre inactive en cliquant sur une autre fenêtre alors que c'était le bouton qui avait le focus, la méthode focusOutEvent n'est pas exécutée.

    C'est ça le problème! Tout dépend donc de ce que le posteur initial recherche.
    Un expert est une personne qui a fait toutes les erreurs qui peuvent être faites, dans un domaine étroit... (Niels Bohr)
    Mes recettes python: http://www.jpvweb.com

  8. #8
    Nouveau membre du Club
    Inscrit en
    Août 2008
    Messages
    41
    Détails du profil
    Informations forums :
    Inscription : Août 2008
    Messages : 41
    Points : 28
    Points
    28
    Par défaut
    Bonjour,

    En fait, j'ai trouver une solution (est-elle bonne, je débute en python ?), en mettant un timer, qui check alors si la fenêtre est active ou non. J'ai mis une fonction facile à voir dans ce cas :

    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
     
    #!/usr/bin/python
    # -*- coding: utf-8 -*-
     
    import sys
    from PyQt4 import QtGui, QtCore
    from time import sleep
    import datetime
     
    class Mywindow(QtGui.QWidget):
     
        def __init__(self):
            QtGui.QSystemTrayIcon.__init__(self)
            self.initUI()
     
        def initUI(self):
            self.ctimer = QtCore.QTimer()
            self.ctimer.start(100)
            QtGui.QToolTip.setFont(QtGui.QFont('SansSerif', 10))
            btn = QtGui.QPushButton('Button', self)
            btn.resize(btn.sizeHint())
            btn.move(10, 10)
            self.setGeometry(300, 300, 250, 150)
     
            self.show()
            # constant timer
            QtCore.QObject.connect(self.ctimer, QtCore.SIGNAL("timeout()"), self.constantUpdate)
     
        def constantUpdate(self):
            if QtGui.QApplication.activeWindow()==self:
                print "has focus !"
                self.setWindowOpacity(0.9)
            else:
                print "has not focus !"
                self.setWindowOpacity(0.25)
     
    def main():
        app = QtGui.QApplication(sys.argv)
        win = Mywindow()
        sys.exit(app.exec_())
     
    if __name__ == '__main__':
        main()
    est-ce politiquement correct comme code ? coté performance, pas de problème. çà me permettrai par exemple de vérifier la version d'un fichier externe comprenant des datas, et de faire un refresh des éléments de l'ui si nouvelle version (créée par un autre utilisateur de l'appli). Je sais pas encore comment faire un refresh d'une ui, prochaine étape lol.

  9. #9
    Nouveau membre du Club
    Inscrit en
    Août 2008
    Messages
    41
    Détails du profil
    Informations forums :
    Inscription : Août 2008
    Messages : 41
    Points : 28
    Points
    28
    Par défaut
    VinsS, solution intéressante, je la garde dans un coin. Par contre en effet, si le bouton a le focus, le widget ne l'a plus, donc çà ne va pas dans ce cas précis. Mais çà va me servir pour autre chose

  10. #10
    Expert éminent
    Avatar de fred1599
    Homme Profil pro
    Lead Dev Python
    Inscrit en
    Juillet 2006
    Messages
    3 817
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Meurthe et Moselle (Lorraine)

    Informations professionnelles :
    Activité : Lead Dev Python
    Secteur : Arts - Culture

    Informations forums :
    Inscription : Juillet 2006
    Messages : 3 817
    Points : 7 110
    Points
    7 110
    Par défaut
    Pour vérifier le focus, on utilise la méthode hasFocus, un truc du genre

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    def constantUpdate(self):
            if self.hasFocus():
                print "has focus !"
                self.setWindowOpacity(0.9)
            else:
                print "has not focus !"
                self.setWindowOpacity(0.25)
    J'ai pas regardé le reste
    Celui qui trouve sans chercher est celui qui a longtemps cherché sans trouver.(Bachelard)
    La connaissance s'acquiert par l'expérience, tout le reste n'est que de l'information.(Einstein)

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

Discussions similaires

  1. focus dans une cellule d'une JTable
    Par coil dans le forum Composants
    Réponses: 5
    Dernier message: 07/07/2010, 17h15
  2. Focus sur une application Windows
    Par mixi dans le forum Général JavaScript
    Réponses: 4
    Dernier message: 13/10/2004, 19h57
  3. Detecter la fermeture d'une fenetre MsDos
    Par Akta3d dans le forum C++Builder
    Réponses: 2
    Dernier message: 13/07/2004, 16h53
  4. [VB6]Passer le focus à une instance précedente
    Par Jeremiah dans le forum VB 6 et antérieur
    Réponses: 13
    Dernier message: 16/09/2003, 10h01
  5. Comment basculer le focus depuis une autre form ?
    Par altahir007 dans le forum Composants VCL
    Réponses: 9
    Dernier message: 03/09/2003, 15h54

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