Précédent   Forum du club des développeurs et IT Pro > Autres langages > Python & Zope > GUI > PySide et PyQt
PySide et PyQt Forum d'entraide sur PySide et PyQt
Partagez cette discussion sur d'autres réseaux sociaux : Viadeo Twitter Google Facebook Digg Delicious MySpace Yahoo
Réponse
 
Outils de la discussion
Publicité
'
Vieux 27/12/2012, 20h24   #1
kiby56
Invité régulier
 
Inscription : août 2008
Messages : 36
Détails du profil
Informations forums :
Inscription : août 2008
Messages : 36
Points : 5
Points : 5
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
kiby56 est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 27/12/2012, 22h43   #2
tyrtamos
Expert Confirmé
 
Avatar de tyrtamos
 
Inscription : décembre 2007
Messages : 1 797
Détails du profil
Informations personnelles :
Localisation : France

Informations forums :
Inscription : décembre 2007
Messages : 1 797
Points : 3 109
Points : 3 109
Bonjour,

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

Code :
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.
__________________
Ne rien ranger permet d'observer la loi universelle d'entropie: l'inévitable convergence vers le chaos...
Mes recettes python: http://www.jpvweb.com
tyrtamos est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 28/12/2012, 04h55   #3
kiby56
Invité régulier
 
Inscription : août 2008
Messages : 36
Détails du profil
Informations forums :
Inscription : août 2008
Messages : 36
Points : 5
Points : 5
Merci,

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

Code :
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()
kiby56 est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 28/12/2012, 07h03   #4
VinsS
Membre Expert
 
Homme
Inscription : octobre 2008
Messages : 972
Détails du profil
Informations personnelles :
Sexe : Homme
Localisation : Belgique

Informations forums :
Inscription : octobre 2008
Messages : 972
Points : 1 454
Points : 1 454
Salut,

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

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

Reprenant ton exemple:
Code :
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
__________________
Vincent
Oqapy . Qarte . PaQager
VinsS est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 28/12/2012, 09h41   #5
tyrtamos
Expert Confirmé
 
Avatar de tyrtamos
 
Inscription : décembre 2007
Messages : 1 797
Détails du profil
Informations personnelles :
Localisation : France

Informations forums :
Inscription : décembre 2007
Messages : 1 797
Points : 3 109
Points : 3 109
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!
__________________
Ne rien ranger permet d'observer la loi universelle d'entropie: l'inévitable convergence vers le chaos...
Mes recettes python: http://www.jpvweb.com
tyrtamos est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 28/12/2012, 10h19   #6
VinsS
Membre Expert
 
Homme
Inscription : octobre 2008
Messages : 972
Détails du profil
Informations personnelles :
Sexe : Homme
Localisation : Belgique

Informations forums :
Inscription : octobre 2008
Messages : 972
Points : 1 454
Points : 1 454
Ben, moi j'ai compris que c'était sur la fenêtre que le focus l'intéressait.

Citation:
... 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.
__________________
Vincent
Oqapy . Qarte . PaQager
VinsS est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 28/12/2012, 10h57   #7
tyrtamos
Expert Confirmé
 
Avatar de tyrtamos
 
Inscription : décembre 2007
Messages : 1 797
Détails du profil
Informations personnelles :
Localisation : France

Informations forums :
Inscription : décembre 2007
Messages : 1 797
Points : 3 109
Points : 3 109
@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.
__________________
Ne rien ranger permet d'observer la loi universelle d'entropie: l'inévitable convergence vers le chaos...
Mes recettes python: http://www.jpvweb.com
tyrtamos est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 28/12/2012, 12h26   #8
kiby56
Invité régulier
 
Inscription : août 2008
Messages : 36
Détails du profil
Informations forums :
Inscription : août 2008
Messages : 36
Points : 5
Points : 5
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 :
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.
kiby56 est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 28/12/2012, 12h33   #9
kiby56
Invité régulier
 
Inscription : août 2008
Messages : 36
Détails du profil
Informations forums :
Inscription : août 2008
Messages : 36
Points : 5
Points : 5
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
kiby56 est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 28/12/2012, 14h14   #10
fred1599
Membre Expert
 
Avatar de fred1599
 
Homme Fred
Enseignant
Inscription : juillet 2006
Messages : 1 329
Détails du profil
Informations personnelles :
Nom : Homme Fred
Localisation : France, Meurthe et Moselle (Lorraine)

Informations professionnelles :
Activité : Enseignant
Secteur : Enseignement

Informations forums :
Inscription : juillet 2006
Messages : 1 329
Points : 1 829
Points : 1 829
Pour vérifier le focus, on utilise la méthode hasFocus, un truc du genre

Code :
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)
fred1599 est déconnecté   Envoyer un message privé Réponse avec citation 00
Réponse Cette discussion est résolue.
Outils de la discussion

Navigation rapide


Fuseau horaire GMT +2. Il est actuellement 03h54.


 
 
 
 
Partenaires

Hébergement Web