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 :

PyQt4: différence entre connexion classique et nouvelle méthode: il y a un paramètre "False" qui est envoyé [QtGui]


Sujet :

PyQt Python

  1. #1
    Expert éminent sénior
    Avatar de Sve@r
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Février 2006
    Messages
    12 689
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Oise (Picardie)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : Aéronautique - Marine - Espace - Armement

    Informations forums :
    Inscription : Février 2006
    Messages : 12 689
    Points : 30 983
    Points
    30 983
    Billets dans le blog
    1
    Par défaut PyQt4: différence entre connexion classique et nouvelle méthode: il y a un paramètre "False" qui est envoyé
    Bonjour à tous

    Comme dit dans le titre, j'ai découvert (si ça se trouve ça fait 15 ans que tout le monde le sait ) qu'il y a une différence entre la connexion signal/slot classique (QObject.connect(item, signal, slot)) et la nouvelle syntaxe de connexion (item.signal.connect(slot)). En effet, dans la première syntaxe le slot est appelé sans paramètre alors que dans la seconde il reçoit un paramètre "False"

    Exemple
    Code python : 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
    #!/usr/bin/env python
    # coding: utf-8
     
    import sys
    from sip import *
    from PyQt4.QtCore import *
    from PyQt4.QtGui import *
     
    def slotBtn(*args, **kwargs):
    	print "args=", args
     
    app=QApplication(sys.argv)
    main=QMainWindow()
    main.setCentralWidget(QWidget(main))
    btn1=QPushButton("Slot classique")
    QObject.connect(
    	btn1,
    	SIGNAL("clicked()"),
    	slotBtn,
    )
    btn2=QPushButton("PySignal")
    btn2.clicked.connect(slotBtn)
    layout=QVBoxLayout(main.centralWidget())
    layout.addWidget(btn1, 0)
    layout.addWidget(btn2, 0)
    main.show()
    app.exec_()

    Comme vous le voyez dans cet exemple minimaliste, la même fonction est connectée à deux boutons distincts chacun par une syntaxe particulière. Lors de l'appui sur le premier bouton, la fonction ne reçoit rien mais si on clique sur le second, elle reçoit "False".

    Je dois dire que ça m'embête un peu car je comptais parfois sur le fait qu'un slot ne reçoive rien pour l'appeler manuellement avec des trucs et détecter donc s'il était appelé par un signal ou bien par moi.
    Est-ce que quelqu'un aurait une explication, voire même essayer de reproduire le comportement initial avec la nouvelle syntaxe ? Surtout qu'avec Qt5 l'ancienne syntaxe n'existe plus.

    En vous remerciant
    Mon Tutoriel sur la programmation «Python»
    Mon Tutoriel sur la programmation «Shell»
    Sinon il y en a pleins d'autres. N'oubliez pas non plus les différentes faq disponibles sur ce site
    Et on poste ses codes entre balises [code] et [/code]

  2. #2
    Expert éminent
    Avatar de tyrtamos
    Homme Profil pro
    Retraité
    Inscrit en
    Décembre 2007
    Messages
    4 462
    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 462
    Points : 9 249
    Points
    9 249
    Billets dans le blog
    6
    Par défaut
    Bonjour,

    Effectivement, le signal "clicked" envoie un booléen "checked" qui correspond à l'état "checkable" du bouton quand il est demandé (setCheckable(True)). Le bouton garde alors un état "a été appuyé" ou "a été relaché".

    Pour pouvoir appeler la méthode séparément du bouton, il suffit de mettre l'argument "checked=None". A l'intérieur de cette méthode si checked==None, c'est qu'on l'a appelé séparément du bouton. Si au contraire la méthode a été appelée par le bouton, checked vaudra False (par défaut) ou True.
    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
    Expert éminent sénior
    Avatar de Sve@r
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Février 2006
    Messages
    12 689
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Oise (Picardie)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : Aéronautique - Marine - Espace - Armement

    Informations forums :
    Inscription : Février 2006
    Messages : 12 689
    Points : 30 983
    Points
    30 983
    Billets dans le blog
    1
    Par défaut
    Merci de tes précieuses informations. En effet ça fonctionne comme tu le décris.
    Je ne te dis pas que ça me fasse vraiment plaisir parce qu'il y a du code que je vais devoir revoir. Surtout que ça devient l'inverse de ce que j'avais prévu (à l'origine le signal "clicked" n'envoyait rien et moi j'envoyais quelque chose pour différencier et maintenant il envoie quelque chose et moi faut que j'envoie spécifiquement "None" à cet emplacement pour différencier).
    Franchement c'est pas cool car quand je lis la doc, je vois juste "avant la syntaxe était celle-ci, maintenant c'est comme ça" ce qui sous-entend que rien ne change dans le comportement alors qu'en réalité le comportement a changé et démerde-toi pour comprendre en quoi. Et sans toi je serais encore en train de galérer et d'anôner péniblement quelques trucs pour tester et deviner ce qui se passe.

    Merci encore

    [edit]Non finalement la modification a été assez simple: auparavant c'était "soit je ne reçois rien (fonction appelée par le bouton) soit je reçois un truc (fonction appelée par moi)". Maintenant c'est "soit je reçois True/False (fonction appelée par le bouton) soit je reçois autre chose (fonction appelée par moi mais en veillant bien à ne pas passer True ou False ce qui est déjà le cas)".
    Donc le test qui était auparavant if arg is not None est devenu if arg not in (True, False) ce qui a été assez rapide à remplacer.

    Donc ok, tout refonctionne super

    Mon Tutoriel sur la programmation «Python»
    Mon Tutoriel sur la programmation «Shell»
    Sinon il y en a pleins d'autres. N'oubliez pas non plus les différentes faq disponibles sur ce site
    Et on poste ses codes entre balises [code] et [/code]

  4. #4
    Expert éminent sénior
    Homme Profil pro
    Architecte technique retraité
    Inscrit en
    Juin 2008
    Messages
    21 283
    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 283
    Points : 36 770
    Points
    36 770
    Par défaut
    Salut,

    Citation Envoyé par Sve@r Voir le message
    Franchement c'est pas cool car quand je lis la doc, je vois juste "avant la syntaxe était celle-ci, maintenant c'est comme ça" ce qui sous-entend que rien ne change dans le comportement alors qu'en réalité le comportement a changé et démerde-toi pour comprendre en quoi.
    Pour moi, l'erreur vient du laxisme permis par SIGNAL("clicked()") car la documentation de Qt4 dit bien que clicked prend un booléen en paramètre.
    Il faudrait écrire: SIGNAL("clicked(bool)").
    Ceci dit, l'introspection marche aussi côté "slot" car ce code:
    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
     
    import sys
    from sip import *
    from PyQt4.QtCore import *
    from PyQt4.QtGui import *
     
    def slotBtn():
    	print ('slot')
     
    app=QApplication(sys.argv)
    main=QMainWindow()
    main.setCentralWidget(QWidget(main))
    btn1=QPushButton("Slot classique")
    QObject.connect(
    	btn1,
    	SIGNAL("clicked()"),
    	slotBtn,
    )
     
     
    btn2=QPushButton("PySignal")
    btn2.clicked.connect(slotBtn)
    layout=QVBoxLayout(main.centralWidget())
    layout.addWidget(btn1, 0)
    layout.addWidget(btn2, 0)
    main.show()
    app.exec_()
    fonctionne bien dans les deux cas (çà ne plante pas en TypeError disant que slotBtn est appelé avec un paramètre alors qu'aucun est déclaré).

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

  5. #5
    Expert éminent sénior
    Avatar de Sve@r
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Février 2006
    Messages
    12 689
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Oise (Picardie)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : Aéronautique - Marine - Espace - Armement

    Informations forums :
    Inscription : Février 2006
    Messages : 12 689
    Points : 30 983
    Points
    30 983
    Billets dans le blog
    1
    Par défaut
    Citation Envoyé par wiztricks Voir le message
    Pour moi, l'erreur vient du laxisme permis par SIGNAL("clicked()") car la documentation de Qt4 dit bien que clicked prend un booléen en paramètre.
    Il faudrait écrire: SIGNAL("clicked(bool)").
    C'est vrai que si on l'écrit sous cette forme, alors le fonctionnement devient identique à la seconde écriture (la fonction se met à recevoir alors un booléen). Et par voie de conséquences, la seconde écriture devait être aussi btn2.clicked[bool].connect(slotBtn).

    Citation Envoyé par wiztricks Voir le message
    Ceci dit, l'introspection marche aussi côté "slot" car ce code fonctionne bien dans les deux cas (çà ne plante pas en TypeError disant que slotBtn est appelé avec un paramètre alors qu'aucun est déclaré).
    Oui et y compris si tu écris la première connexion avec SIGNAL("clicked(bool)"). Mais mon souci primitif était que quand je rajoutais un paramètre au slot, paramètre dédié à mes appels personnels et mis à None par défaut, ce paramètre était alors aussi utilisé par le booléen du "clicked" alors que je ne m'y attendais pas (mon slot testait le None pour détecter l'origine de l'appel et donc quand j'ai remplacé la première connexion par la seconde tout mon programme a commencé à cafouiller car les clics sur les boutons ne répondaient plus correctement).
    Mon Tutoriel sur la programmation «Python»
    Mon Tutoriel sur la programmation «Shell»
    Sinon il y en a pleins d'autres. N'oubliez pas non plus les différentes faq disponibles sur ce site
    Et on poste ses codes entre balises [code] et [/code]

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

Discussions similaires

  1. Récupérer ce qui est envoyé en méthode post
    Par startx25 dans le forum Général JavaScript
    Réponses: 12
    Dernier message: 10/03/2015, 10h36
  2. Classe: faire la différence entre un attribut et une méthode
    Par rambc dans le forum Général Python
    Réponses: 5
    Dernier message: 15/11/2009, 16h44
  3. Différence entre les sources de connexion
    Par Djimson dans le forum VB 6 et antérieur
    Réponses: 4
    Dernier message: 20/12/2006, 18h08
  4. Réponses: 2
    Dernier message: 31/05/2006, 18h49
  5. Différence entre méthode d'inclusion d'une feuille CSS
    Par Death83 dans le forum Mise en page CSS
    Réponses: 14
    Dernier message: 11/01/2006, 15h00

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