Partage
  • Partager sur Facebook
  • Partager sur Twitter

Connecter un tableau (de QPushButton) à un slot

Sujet résolu
    26 juin 2019 à 12:19:00

    Bonjour à tous,

    Voila je suis bloquée, je vous explique la situation :

    J'ai créer un tableau de QPushButton placé sur l'écran avec un GridLayout (oui je sais utiliser un QTableView aurait été plus malin mais comme c'est relier à différentes fonctions en partie pour écrire dans un fichier externe et que ca fonctionne je vais le garder pour le moment 0:) )

    Je voudrais qu'en cliquant sur un des boutons cela appelle un slot (qui sert à ouvrir une autre fenetre);

    EN gros un truc comme ça (sauf que c'est pas correct du tout):

    connect(lab[i],SIGNAL(clicked()),this,SLOT(ouvrirFenetre(i)));

    ou i correspondrait au numéro de la case cliquée

    Pour parer le probleme du manque d'argument du signal j'ai essayé de créer mon propre signa avec mousePressEvent mais ca marche pas (il ne trouv pas le signal).

    L'autre alternative aurait ete d'utiliser sender() pour récupérer l'expéditeur mais ca marche pas non plus ...

    et enfin lab[i] ne peut vraiment fonctionner, il me semble, que dans une boucle, or ça ne marche pas non plus ...

    Bon en réalité rien ne marche et je ne vois plus quoi essayer ...

    Donc j'ai codé comme un bourin avec une liste de connect et de fonction comme ca (c'est assez degueu et pas pratique du tout)

    connect(lab[0],SIGNAL(clicked()),this,SLOT(ouvrirFenetre0()));
    connect(lab[1],SIGNAL(clicked()),this,SLOT(ouvrirFenetre1()));
    connect(lab[2],SIGNAL(clicked()),this,SLOT(ouvrirFenetre2()));
    connect(lab[3],SIGNAL(clicked()),this,SLOT(ouvrirFenetre3()));
    connect(lab[4],SIGNAL(clicked()),this,SLOT(ouvrirFenetre4()));
    connect(lab[5],SIGNAL(clicked()),this,SLOT(ouvrirFenetre5()));
    connect(lab[6],SIGNAL(clicked()),this,SLOT(ouvrirFenetre6()));

    Aidez moi SVPPPPPPP 

    Merci d'avance ;)

    • Partager sur Facebook
    • Partager sur Twitter
      26 juin 2019 à 14:41:22

      Salut,

      J'ai pas vraiment le temps de vérifier ce que je vais dire, mais les pistes que je peux te donner sont std::bind et les lambda. Et il faut utiliser la syntaxe Qt5 des connect, la syntaxe à base de macro est là pour des raisons de compatibilité et est moins performante.

      ça doit donner quelque chose proche de (std::bind)

      for(int i = 0; i < 7; ++i)
      {
        connect(lab[i], &QPushButton::clicked, this, std::bind(&MaClasse::ouvrirFenetre, this, i));
      }

      ou (lambda)

      for(int i = 0; i < 7; ++i)
      {
        connect(lab[i], &QPushButton::clicked, this, [this, i](){this->ouvrirFenetre(i);});
      }




      -
      Edité par romantik 26 juin 2019 à 15:15:31

      • Partager sur Facebook
      • Partager sur Twitter
      Dream on, Dream on, Dream until your dream comes true
        27 juin 2019 à 1:31:36

        Salut,

        Tu devrais t'intéresser à QSignalMapper, qui est justement prévu pour ce genre d'usage ;)

        • Partager sur Facebook
        • Partager sur Twitter
        Ce qui se conçoit bien s'énonce clairement. Et les mots pour le dire viennent aisément.Mon nouveau livre : Coder efficacement - Bonnes pratiques et erreurs  à éviter (en C++)Avant de faire ce que tu ne pourras défaire, penses à tout ce que tu ne pourras plus faire une fois que tu l'auras fait
          27 juin 2019 à 2:36:00

          koala01 a écrit:

          Salut,

          Tu devrais t'intéresser à QSignalMapper, qui est justement prévu pour ce genre d'usage ;)

          De mémoire, cette classe est depréciée, non?
          • Partager sur Facebook
          • Partager sur Twitter

          Eug

            28 juin 2019 à 3:04:17

            Ah, c'est possible :-°:'(.  Sur ce coup, la doc de Qt manque de clarté, car rien ne l'indique de son côté:diable:.

            Ceci étant dit, ce n'est pas une raison pour proposer l'utilisation de bind, alors que les expressions lambda feraient parfaitement l'affaire ;) :

            connect(button1, &QPushButton::clicked, this,
                    [&](){openWindow(1);});
            connect(button2, &QPushButtonclicked, this,
                    [&](){openWindow(2);});
            connect(button3, &QPushButtonclicked, this,
                    [&](){openWindow(3);});
            connect(button4, &QPushButtonclicked, this,
                    [&](){openWindow(4);});

            En outre, je ne suis pas persuadé du tout (je suis même intimement persuadé du contraire) que ce soit une bonne idée de vouloir regrouper l'ouverture de plusieurs fenêtres au sein d'une unique fonction :-°:

            Cela ne me gênerait pas **trop** d'utiliser cette technique pour paramétrer l'ouverture d'une même fenêtre en en changeant quelques informations comme le titre, le texte de base ou l'état d'un (ou de plusieurs) widgets.  Et encore !

            Par contre, je vois au moins trois raisons qui devraient nous empêcher d'y avoir recours pour l'ouverture de fenêtres différentes:

            1- cela contrevient à l'OCP (Open Closed principle ou principe "ouvert fermé"): une fois que le comportement du code a été validé, il n'y a plus de raison de décider de le modifier (sauf pour résoudre des bugs ou des problèmes de performances).

            Dans le cas présent, il arrivera tôt ou tard que tu veuilles rajouter une nouvelle fenêtre et que tu oublieras de rajouter la prise en compte de cette possibilité à ta fonction, et tu perdras un temps bête à te demander pourquoi ta fenêtre ne s'ouvre pas :'(.

            2- Le contenu de chaque fenêtre étant -- par nature -- différent, si tu veux paramétrer ce contenu, tu devras prévoir une logique différente pour chaque fenêtre, ce qui contreviendrait non seulement à l'OCP, mais aussi au SRP.

            3- Le contenu de chaque fenêtre étant -- par nature -- différent, le traitement final, la récupération des informations fournies par l'utilisateur par le biais de chaque fenêtre se fera lui aussi de manière  différente, ce qu contreviendrait également à l'OCP et au SRP.

            -
            Edité par koala01 28 juin 2019 à 3:21:03

            • Partager sur Facebook
            • Partager sur Twitter
            Ce qui se conçoit bien s'énonce clairement. Et les mots pour le dire viennent aisément.Mon nouveau livre : Coder efficacement - Bonnes pratiques et erreurs  à éviter (en C++)Avant de faire ce que tu ne pourras défaire, penses à tout ce que tu ne pourras plus faire une fois que tu l'auras fait
              28 juin 2019 à 11:50:25

              koala01 a écrit:

              Ceci étant dit, ce n'est pas une raison pour proposer l'utilisation de bind, alors que les expressions lambda feraient parfaitement l'affaire ;)

              Un problème avec bind ? je pensais que ça servait justement pour ce genre de problème, fabriquer une fonction à partir d'une autre pour avoir la signature qui nous convient.

              • Partager sur Facebook
              • Partager sur Twitter
              Dream on, Dream on, Dream until your dream comes true
                28 juin 2019 à 12:00:10

                koala01 a écrit:

                Ah, c'est possible :-°:'(.  Sur ce coup, la doc de Qt manque de clarté, car rien ne l'indique de son côté:diable:.

                si, si, 6ème ligne de la doc: "This class is obsolete. It is provided to keep old source code working. We strongly advise against using it in new code."

                • Partager sur Facebook
                • Partager sur Twitter
                  28 juin 2019 à 14:12:23

                  romantik a écrit:

                  Un problème avec bind ? je pensais que ça servait justement pour ce genre de problème, fabriquer une fonction à partir d'une autre pour avoir la signature qui nous convient.

                  C'est pas vraiment un problème, car oui, c'est effectivement fait pour :D.

                  C'est juste  que tu as presque de la chance que la syntaxe "simple" puisse fonctionner, car, dans certains cas, tu te retrouverais à  devoir utiliser une syntaxe proche de

                  std::bind(&MyStruct::theFunction, std::ref(theVariable), std::placeholders::_1))
                  Et puis, de manière générale, la syntaxe à base de lambda est beaucoup plus courte à écrire, car on a
                          connect(lab[i], &QPushButton::clicked, parent, std::bind(&MainWindow::ouvrirFenetre, parent, i));
                  // contre
                          connect(lab[i], &QPushButton::clicked, parent, [&, i](){parent->ouvrirFenetre(i);});
                  Enfin, on s'habitue tellement à travailler avec les expressions lambda pour toutes sortes de choses que cela en devient presque la solution que l'on choisi "par défaut" :'(

                  -
                  Edité par koala01 28 juin 2019 à 14:13:19

                  • Partager sur Facebook
                  • Partager sur Twitter
                  Ce qui se conçoit bien s'énonce clairement. Et les mots pour le dire viennent aisément.Mon nouveau livre : Coder efficacement - Bonnes pratiques et erreurs  à éviter (en C++)Avant de faire ce que tu ne pourras défaire, penses à tout ce que tu ne pourras plus faire une fois que tu l'auras fait
                    28 juin 2019 à 15:01:26

                    Koala01 a tout dit.

                    QT5 a une nouvelle syntaxe qui va te permettre de faire des connexions te permettant une vérification de compatibilité à la compilation (et non plus à l'exécution comme c'était le cas <QT5).

                    Puis je ne peux que joindre Koala01 sur les expressions lambda.

                    A+

                    • Partager sur Facebook
                    • Partager sur Twitter
                      28 juin 2019 à 15:29:54

                      Didy7 a écrit:

                      Koala01 a tout dit.

                      QT5 a une nouvelle syntaxe qui va te permettre de faire des connexions te permettant une vérification de compatibilité à la compilation (et non plus à l'exécution comme c'était le cas <QT5).

                      Puis je ne peux que joindre Koala01 sur les expressions lambda.

                      A+


                      Heu, tu veux parler de Qt6, là, non ??? :D
                      • Partager sur Facebook
                      • Partager sur Twitter
                      Ce qui se conçoit bien s'énonce clairement. Et les mots pour le dire viennent aisément.Mon nouveau livre : Coder efficacement - Bonnes pratiques et erreurs  à éviter (en C++)Avant de faire ce que tu ne pourras défaire, penses à tout ce que tu ne pourras plus faire une fois que tu l'auras fait
                        29 juin 2019 à 19:44:53

                        Merci beaucoup a vous pour vos réponses si rapides, je vais essayer les expressions lambda du coup !

                        Koala01, si en l'occurence mes fenetres vont etre "identiques" dans leur présentation c'est juste le fichier .txt qu'elles vont charger qui sera différent, en soit je n'ouvre d'ailleurs qu'une seule fenetre c'est juste en fonction du QPushbutton que le fichier support changera (je sais pas si c'est très clair ....)

                        En tout cas merci pour ces pistes ;)

                        • Partager sur Facebook
                        • Partager sur Twitter

                        Connecter un tableau (de QPushButton) à un slot

                        × Après avoir cliqué sur "Répondre" vous serez invité à vous connecter pour que votre message soit publié.
                        × Attention, ce sujet est très ancien. Le déterrer n'est pas forcément approprié. Nous te conseillons de créer un nouveau sujet pour poser ta question.
                        • Editeur
                        • Markdown