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 :

Récupérer l'action avec un signal triggered() [QtCore]


Sujet :

PyQt Python

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre éclairé Avatar de bastou93
    Homme Profil pro
    Étudiant
    Inscrit en
    Août 2010
    Messages
    217
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Seine Saint Denis (Île de France)

    Informations professionnelles :
    Activité : Étudiant
    Secteur : Aéronautique - Marine - Espace - Armement

    Informations forums :
    Inscription : Août 2010
    Messages : 217
    Par défaut Récupérer l'action avec un signal triggered()
    Bonjour à tous,

    Je suis un peu coincé sur un problème que je pense tout bête.

    Dans ma classe je crée une liste d'action qui sont affiché dans un menu.
    Je crée la connection via le signal "triggered"

    Le problème c'est que je récupère uniquement la valeur de mon action si elle est check ou pas, mais impossible de savoir quelle action a été déclenché.
    Car j'aimerai faire un traitement différent.
    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
    def createActionsMenu(self):
            self.actionsList = []
            # dump
            self.action1 = QAction(QIcon(':/icon16/tab'), 'action1', self)
            self.actionsList.append(self.action1)
            # engine
            self.action2 = QAction(QIcon(':/icon16/tab'), 'action2', self)
            self.actionsList.append(self.action2)
     
        def createConnections(self):
            for action in self.actionsList:
                action.setCheckable(True)
                action.triggered.connect(self.displayChild) 
     
    @pyqtSlot(bool)
        def displayChild(self, b):
            pass
    Merci a tous,

    Bastien

  2. #2
    Expert confirmé

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

    Informations forums :
    Inscription : Octobre 2008
    Messages : 4 305
    Par défaut
    Salut,

    Soit un slot différent pour chaque action, soit une lambda comme ceci:
    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
     
    def createActionsMenu(self):
            self.actionsList = []
            # dump
            self.action1 = QAction(QIcon(':/icon16/tab'), 'action1', self)
            self.action1.setObjectName('action1')
            self.actionsList.append(self.action1)
            # engine
            self.action2 = QAction(QIcon(':/icon16/tab'), 'action2', self)
            self.action1.setObjectName('action1')
            self.actionsList.append(self.action2)
     
        def createConnections(self):
            for action in self.actionsList:
                action.setCheckable(True)
                action.triggered.connect(lambda who=action.objectName(): self.displayChild(who))
     
        def displayChild(self, sender):
            print sender

  3. #3
    Expert confirmé
    Avatar de tyrtamos
    Homme Profil pro
    Retraité
    Inscrit en
    Décembre 2007
    Messages
    4 486
    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 486
    Billets dans le blog
    6
    Par défaut
    Quand on a plusieurs signaux qui activent la même méthode, on peut utiliser partial du module functools pour passer un paramètre supplémentaire.

    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
    import sys
    from functools import partial
    from PyQt4 import QtCore, QtGui
     
    #############################################################################
    class Fenetre(QtGui.QWidget):
     
        def __init__(self, parent=None):
            super(Fenetre, self).__init__(parent)
     
            self.bouton1 = QtGui.QPushButton(u"bouton 1", self)
            self.bouton1.clicked.connect(partial(self.clictest, 1))
     
            self.bouton2 = QtGui.QPushButton(u"bouton 2", self)
            self.bouton2.clicked.connect(partial(self.clictest, 2))
     
            posit = QtGui.QGridLayout()
            posit.addWidget(self.bouton1, 0, 0)
            posit.addWidget(self.bouton2, 1, 0)
            self.setLayout(posit)
     
        def clictest(self, n):
            print("clic bouton", n)
     
    #############################################################################
    if __name__ == "__main__":
        app = QtGui.QApplication(sys.argv)
        fen = Fenetre()
        fen.setAttribute(QtCore.Qt.WA_DeleteOnClose)
        fen.show()
        sys.exit(app.exec_())
    Dans ce code, quand on clique sur le bouton 1, le signal passe l'argument 1 à la méthode, qui peut ainsi repérer que le signal vient du bouton 1.

    Il y a une solution concurrente à partial dans Qt4: QSignalMapper. Mais je trouve partial plus simple.

  4. #4
    Expert éminent
    Homme Profil pro
    Architecte technique retraité
    Inscrit en
    Juin 2008
    Messages
    21 704
    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 704
    Par défaut
    Salut,

    Si on regarde du cote C++, il est possible de récupérer le widget qui a émis le signal qui a provoque l’exécution du slot.
    Dans l'exemple de Tyrtamos, on peut écrire:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
        def clictest(self, n):
            sender = QtCore.QObject.sender(self)
            ...
    Et on récupère l'instance de PushButton dans "sender".

    Avec des QAction, c'est pareil.
    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
    from PyQt4.QtGui import QApplication, QAction, QMainWindow
    from PyQt4.QtCore import QObject
     
    def do_action():
        z = QObject.sender(main)
        print (z.text())
     
    if __name__ == '__main__':
        app = QApplication([])
        main = QMainWindow()
        menu = main.menuBar().addMenu('actions')
        for x in range(5):
            a = QAction('action-%d' % x, main)
            menu.addAction(a)
            a.triggered.connect(do_action)
        main.show()
        app.exec()
    - W
    Architectures post-modernes.
    Python sur DVP c'est aussi des FAQs, des cours et tutoriels

  5. #5
    Expert confirmé
    Avatar de tyrtamos
    Homme Profil pro
    Retraité
    Inscrit en
    Décembre 2007
    Messages
    4 486
    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 486
    Billets dans le blog
    6
    Par défaut
    Bonjour wiztricks,

    Intéressant le "QtCore.QObject.sender()", merci!

    Petite question annexe: si la méthode a été déclenchée par un signal "clicked" de souris, est-ce qu'on pourrait avec ça tester si c'est le bouton gauche ou le bouton droit qui a été cliqué?

  6. #6
    Membre éclairé Avatar de bastou93
    Homme Profil pro
    Étudiant
    Inscrit en
    Août 2010
    Messages
    217
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Seine Saint Denis (Île de France)

    Informations professionnelles :
    Activité : Étudiant
    Secteur : Aéronautique - Marine - Espace - Armement

    Informations forums :
    Inscription : Août 2010
    Messages : 217
    Par défaut
    Merci à tous,

    j'ai implémenter sender()

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    action = monmdi.sender()
    et ensuite je parcours ma liste avec action.text(), ca marche TOP!

    Pour tyrtamos comme le sender() retourne un QObject, je ne pense pas qu'il y ai de moyen de récupérer l'event... A voir

  7. #7
    Expert éminent
    Homme Profil pro
    Architecte technique retraité
    Inscrit en
    Juin 2008
    Messages
    21 704
    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 704
    Par défaut
    Citation Envoyé par tyrtamos Voir le message
    Petite question annexe: si la méthode a été déclenchée par un signal "clicked" de souris, est-ce qu'on pourrait avec ça tester si c'est le bouton gauche ou le bouton droit qui a été cliqué?
    Dans QApplication, un appel a mouseButtons() retournera Qt.LeftButton si "the left button is pressed", etc...
    *but* le slot action.triggered est poste après le release du Button => "trop tard": Qt.NoButton.

    Comment se passer d'une surcharge des mouseEvent dans ce cas la? Je ne sais pas.
    Posez la question dans le forum Qt: un des velus qui fréquentent le forum a peut être travaille la dessus.

    Citation Envoyé par bastou93 Voir le message
    et ensuite je parcours ma liste avec action.text(), ca marche TOP!
    Pour faire mumuse: aucune importance.
    Dans le cas général, action.text() sera "variable" because I18N.
    Préférez passer par action.setObjectName('action1') / action.objectName() comme suggéré par VinsS.
    Ce nom la sera "interne" et donc "a vous".

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

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

Discussions similaires

  1. Déclencher une action avec un chrono
    Par Oberown dans le forum Général JavaScript
    Réponses: 3
    Dernier message: 20/09/2005, 14h22
  2. [JTextField] Déclencher une action avec la touche ENTER
    Par tchoukapi dans le forum Composants
    Réponses: 10
    Dernier message: 19/09/2005, 14h37
  3. [VB.NET] [ODBC] Récupérer des valeurs avec requête ODBC?
    Par Pleymo dans le forum Windows Forms
    Réponses: 5
    Dernier message: 04/03/2005, 16h38
  4. Réponses: 4
    Dernier message: 27/04/2004, 14h45
  5. Réponses: 2
    Dernier message: 29/03/2004, 13h44

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