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 :

Problème PyQt5 boutons


Sujet :

PyQt Python

  1. #1
    Futur Membre du Club
    Homme Profil pro
    Ingénieur géologue
    Inscrit en
    Avril 2019
    Messages
    12
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Moselle (Lorraine)

    Informations professionnelles :
    Activité : Ingénieur géologue
    Secteur : Industrie

    Informations forums :
    Inscription : Avril 2019
    Messages : 12
    Points : 5
    Points
    5
    Par défaut Problème PyQt5 boutons
    Bonjour,
    Je teste la création de boutons avec PyQt5.
    Les boutons créés directement fonctionnent alors que celui créé par l'intermédiaire d'une méthode ne fonctionne pas.
    Pourriez-vous me dire pourquoi?
    Je joins le code ci-dessous:

    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
    import sys
    from PyQt5.QtWidgets import QApplication, QWidget, QPushButton
    from PyQt5.QtGui import QIcon
    from PyQt5.QtCore import pyqtSlot
     
    class App(QWidget):
     
        def __init__(self):
            super().__init__()
            self.title = 'PyQt5 button - pythonspot.com'
            self.left = 100
            self.top = 100
            self.width = 320
            self.height = 200
            self.initUI()
     
        def initUI(self):
            self.setWindowTitle(self.title)
            self.setGeometry(self.left, self.top, self.width, self.height)
     
            btn1 = QPushButton('btn1', self)
            btn1.setToolTip('exemple de bouton')
            btn1.move(100,70)
            btn1.clicked.connect(self.on_click)
            btn2 = QPushButton('btn2', self)
            btn2.setToolTip('btn2')
            btn2.move(150,20)
            btn2.clicked.connect(self.on_click)
     
            browseButton = self.createButton("btn3", self.on_click)
            browseButton.show()
     
            self.show()
     
        def createButton(self, text, member=None):
            bouton = QPushButton(text)
            bouton.setToolTip(text)
            bouton.move(150,90)
            if (member != None) : bouton.clicked.connect(member);
            return bouton
     
        @pyqtSlot()
        def on_click(self):
            print('PyQt5 button click')
     
    if __name__ == '__main__':
        app = QApplication(sys.argv)
        ex = App()
        sys.exit(app.exec_())
    else:
    #    app = QApplication(sys.argv)
        ex = App()

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

    Citation Envoyé par BrDep Voir le message
    Les boutons créés directement fonctionnent alors que celui créé par l'intermédiaire d'une méthode ne fonctionne pas.
    Pourriez-vous me dire pourquoi?
    Les déclarations des 2 boutons btn1 et btn2 mentionnent bien qu'ils appartiennent à la fenêtre, mais pas le 3ème bouton browseButton. Il suffit de modifier la ligne dans la méthode createButton comme suit:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    bouton = QPushButton(text, self)
    Une autre solution serait d'utiliser QGridLayout, par exemple, pour préciser le positionnement des 3 boutons dans la fenêtre:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
            layout = QGridLayout()
            layout.addWidget(btn1, 0, 0)
            layout.addWidget(btn2, 1, 0)
            layout.addWidget(browseButton, 2, 0)
            self.setLayout(layout)
    D'une façon générale, il faut garder à l'esprit qu'une variable locale (=non précédée par "self") crée dans une méthode est détruite à la fin de cette méthode. Si on veut que l'objet pointé par cette variable perdure, il faut qu'un lien entre l'objet et d'autres éléments existants (ici la fenêtre QWidget) perdure.

  3. #3
    Futur Membre du Club
    Homme Profil pro
    Ingénieur géologue
    Inscrit en
    Avril 2019
    Messages
    12
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Moselle (Lorraine)

    Informations professionnelles :
    Activité : Ingénieur géologue
    Secteur : Industrie

    Informations forums :
    Inscription : Avril 2019
    Messages : 12
    Points : 5
    Points
    5
    Par défaut Un grand Merci
    Bonjour tyrtamos,

    Bravo, je comprenais qu'il fallait que ce 3ème bouton devait avoir un lien avec la fenêtre mais je croyais que le return 'objet' permettait de créer ce lien.
    Cela fonctionne maintenant comme je le souhaite.
    Naturellement, le but final est de déclarer les 3 boutons à l'aise de la méthode createButton().

    En ce qui concerne la 2ème partie de ta réponse, je voulais éviter les H et V layout. Cette solution me semble moins élégante...

    Encore une fois bravo

  4. #4
    Expert éminent
    Avatar de tyrtamos
    Homme Profil pro
    Retraité
    Inscrit en
    Décembre 2007
    Messages
    4 483
    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 483
    Points : 9 282
    Points
    9 282
    Billets dans le blog
    6
    Par défaut
    Citation Envoyé par BrDep Voir le message
    je croyais que le return 'objet' permettait de créer ce lien.
    Le "return bouton" ne renvoie pas la variable bouton mais son contenu (l'objet pointé par elle), ce qui permet à cette variable d'être supprimée en fin de méthode.


    Citation Envoyé par BrDep Voir le message
    je voulais éviter les H et V layout. Cette solution me semble moins élégante...
    C'est pourtant une sacré facilité, même avec le Designer. Les classes qui permettent le positionnement des widgets, simplifient le développement puisqu'une modification nécessaire de taille de la fenêtre ne nécessite pas de recalculer les coordonnées de chaque widget pour les replacer un à un à la bonne place. Elles ont aussi le gros avantage de repositionner automatiquement les widgets quand la fenêtre qui les contient est redimensionnée par l'utilisateur.

  5. #5
    Futur Membre du Club
    Homme Profil pro
    Ingénieur géologue
    Inscrit en
    Avril 2019
    Messages
    12
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Moselle (Lorraine)

    Informations professionnelles :
    Activité : Ingénieur géologue
    Secteur : Industrie

    Informations forums :
    Inscription : Avril 2019
    Messages : 12
    Points : 5
    Points
    5
    Par défaut Merci pour ces précieux conseils.
    Merci pour ces précieux conseils.
    Cordialement,

  6. #6
    Expert éminent sénior
    Avatar de Sve@r
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Février 2006
    Messages
    12 735
    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 735
    Points : 31 060
    Points
    31 060
    Billets dans le blog
    1
    Par défaut
    Bonjour
    Citation Envoyé par BrDep Voir le message
    if (member != None) : bouton.clicked.connect(member);
    On ne teste pas "None" via l'opérateur "égal/non égal" mais par "is/is not". Et ce pour 2 raisons
    • None n'est pas une valeur, c'est un état. On "est" ou on "n'est pas" None. Mais on n'est pas égal à None
    • L'opérateur "is" est le seul opérateur qui ne peut pas être surchargé
      Exemple
      Code python : Sélectionner tout - Visualiser dans une fenêtre à part
      1
      2
      3
      4
      5
      6
      7
      8
      9
      >>> class toto:
      …	def __eq__(self, x): return Truedef __ne__(self, x): return False
      …
      >>> a=toto()
      >>> a == None
      True
      >>> a != None
      False


    Sinon les parenthèses au "if" et le point-virgule final, c'est un reste de C ???

    if member is not None: bouton.clicked.connect(member).

    Et ça devient pire si tu fais la même chose avec True et False car là c'est le mur. Exemple
    Code python : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    >>> var="Hello"
    >>> if var is True: print("ok")
    …
    >>> if var == True: print("ok")
    …
    >>> if var: print("ok")
    …
    ok

    Donc "is" pour vérifier None, et simplement utiliser l'expression dans un test booléen sans regarder True et False pour faire le test.

    Citation Envoyé par BrDep Voir le message
    je voulais éviter les H et V layout. Cette solution me semble moins élégante...
    Mauvais à priori car c'est ce qu'il y a de mieux. Quand tu maitrises les layout, tu fais des applications superbes. Les widgets s'alignent les unes aux autres, s'agrandissent avec la fenêtre, etc. Et sans se casser le luc à chercher la position avec les move(x, y) qui ne veulent plus rien dire quand la fenêtre change de taille (remarque j'ai commencé comme toi, et j'avais même définit un slot qui réagissait au signal de redimensionnement pour recalculer les positions)...

    Mais faut s'y mettre. Au début je galérais avec les QSpacer et ça marchait jamais puis j'ai compris comment ça marche.
    Déjà j'évite généralement les Grid. La grid son souci c'est que tout est lié. Si par exemple la cellule L1C1 s'élargit de 30, l'élargissement sera appliqué pour toute la colonne. Donc j'utilise plutôt différents HBoxLayout qui récupèrent les widgets horizontaux, puis je places ces HBoxLayout dans un VBoxLayout.
    Là dans ton exemple tu places le premier bouton en (100,70). Le second en (150, 20) et le 3° en (150, 90) donc (je peux pas tester je suis provisoirement sans PyQt donc je fais ça à l'estime) le premier à gauche et les deux autres un peu à droite et l'un au dessus de l'autre. Donc là typiquement je créerais un QVBoxLayout pour placer les boutons 2 et 3 et je mettrais ce QVBoxLayout dans un QHBoxLayout qui contiendrait aussi le bouton1 et un stretch pour l'espace vide entre les deux.

    Et l'élargissement se règle au placement. Exemple
    Code c : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    lay=QHBoxLayout()
    lay.addWidget(btn1, 1)
    lay.addWidget(btn2, 2)
    lay.addWidget(btn3, 3)

    La somme des 3 facteurs 1+2+3 fait 6. Le premier bouton aura alors un facteur d'élargissement de 1/6° de la largeur de la ligne. Le second aura 2/6° (1/3) et le 3° aura 3/6 (1/2). Et on peut aussi modifier ça après coup avec setStretch(). Plus un setContentsMargin() pour gérer l'espace entre le bord et les widgets et un setSpacing() pour gérer l'espace entre les widgets et c'est réglé quoi.

  7. #7
    Futur Membre du Club
    Homme Profil pro
    Ingénieur géologue
    Inscrit en
    Avril 2019
    Messages
    12
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Moselle (Lorraine)

    Informations professionnelles :
    Activité : Ingénieur géologue
    Secteur : Industrie

    Informations forums :
    Inscription : Avril 2019
    Messages : 12
    Points : 5
    Points
    5
    Par défaut
    Merci Sve@r,

    Entre temps, et concernant les layouts, j'ai regardé quelques exemples et, je l'avoue, ils sont très utiles lorsque l'on en utilise plusieurs afin de découper la fenêtre.
    Je m'aperçois petit à petit que mes remarques initiales sont celles d'un débutant.

    Pour le NONE, merci des renseignements. C'est bon à savoir.

    Bonne soirée,

Discussions similaires

  1. [Debutant] Problème de boutons
    Par Welldone dans le forum Débuter
    Réponses: 5
    Dernier message: 08/07/2005, 16h37
  2. [C#] problème de bouton transparent
    Par mbibim63 dans le forum Windows Forms
    Réponses: 4
    Dernier message: 17/05/2005, 15h50
  3. Réponses: 24
    Dernier message: 11/01/2005, 11h12
  4. [FLASH MX]Problème de bouton et de _level
    Par Geilgestorm dans le forum Flash
    Réponses: 9
    Dernier message: 01/07/2004, 17h37
  5. Problème de boutons radio
    Par BRAUKRIS dans le forum Composants
    Réponses: 3
    Dernier message: 03/06/2004, 03h41

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