Partage
  • Partager sur Facebook
  • Partager sur Twitter

Affichage de a liste des favoris(public slot)

C++ / Qt

    7 septembre 2017 à 18:02:15

    Bonjour à tous

    toujours dans le cadre du projet Navigo que je suis en train de terminer, j'ai un bouton dans ma barre d'outils. Quand j'appuie dessus, alors la liste des favoris enregistrés dans un fichier .ini grâce à un QSettings, doit s'afficher.

    J'ai utilisé les lambda fonctions enseignées par gbdivers et j'ai omis de mettre les tests de pointeurs (pour le code propre)

    Voici une partie des messages que j'obtiens :

    Impossible d'obtenir la sortie du débogage.

    Le programme s'est terminé subitement.

    Et voici le code du public slot qui s'en charge (appremment, il y a un bug donc) :

    void FenPrincipale::ouvrirListeFavoris(){
    
        QStringList keys=settings->allKeys();
    
        for(auto it=keys.begin();it !=keys.end();it++){
        QCheckBox *checkBox = new QCheckBox(settings->value(*it).toString(),groupeFavorites);
        checkBox->setChecked(true);
        QObject::connect(checkBox,&QCheckBox::stateChanged,checkBox,[=](){checkBox->hide();  });
        QObject::connect(checkBox,&QCheckBox::clicked,this,[=](){
            QWidget *page=new QWidget;
            ui->onglets->addTab(page,urlDefault);
            QWebView *pageWeb = new QWebView(page);
            pageWeb->load(QUrl(settings->value(*it).toString()));
             });
    
        vboxGroupeFavorites->addWidget(checkBox);
        }                 
    
        groupeFavorites->setLayout(vboxGroupeFavorites);
        dialogListeFavoris->show();
    }
    

    Merci pour votre aide.



    -
    Edité par pseudo-simple 7 septembre 2017 à 21:28:54

    • Partager sur Facebook
    • Partager sur Twitter
      9 septembre 2017 à 11:13:55

      Bonjour, Je fais remonter le sujet mis en ligne depuis plusieurs jours pour savoir si vous avez des idées.

      Merci

      -
      Edité par pseudo-simple 9 septembre 2017 à 11:14:36

      • Partager sur Facebook
      • Partager sur Twitter
        9 septembre 2017 à 11:42:30

        YES, man a écrit:

        j'ai omis de mettre les tests de pointeurs (pour le code propre)

        Est-ce que tu as corrigé ce problème ?
        • Partager sur Facebook
        • Partager sur Twitter
          9 septembre 2017 à 12:02:01

          gbdivers, je sais que tu as raison sur ce point. Je compte le faire en optimisation du code.

          Je voudrais bien que le code fonctionne déjà "grossièrement". Pour la propreté du code, je sais que c'est toi qui a raison.

          Je pense que pour l'instant, le bug que j'ai peut être corrigé même si je ne fais pas le test sur chaque pointeur pris à part.

          • Partager sur Facebook
          • Partager sur Twitter
            9 septembre 2017 à 13:18:19

            Vérifier les pointeurs n'est pas un question de proprete du code. C'est indispensable pour minimiser les problèmes avec les pointeurs. Si tu regles pas un problème aussi important, on ne va pas s'embeter avec les details.
            • Partager sur Facebook
            • Partager sur Twitter
              9 septembre 2017 à 13:52:47

              J'ai ajouté les tests, le problème est toujours au moment où je clique sur un des checkBox pour lancer dans un nouvel onglet le lien.

              Apparemment, c'est un lien avec le deuxième QObject::connect

              void FenPrincipale::ouvrirListeFavoris(){
              
                  QStringList keys=settings->allKeys();
              
                  for(auto it=keys.begin();it !=keys.end();it++){
                      QCheckBox *checkBox = new QCheckBox(settings->value(*it).toString(),groupeFavorites);
                      if(!checkBox)
                      {
                          std::cout<<"Problème checkBox"<<"\n";
                          return;
                      }
                      checkBox->setChecked(true);
                      QObject::connect(checkBox,&QCheckBox::stateChanged,this,[=](){checkBox->hide();  });
                      QObject::connect(checkBox,&QCheckBox::clicked,this,[=](){
                          QWidget *page=new QWidget;
                          if(!page)
                          {
                              std::cout<<"problème page";
                              return;
                          }
                          ui->onglets->addTab(page,urlDefault);
                          QWebView *pageWeb = new QWebView(page);
                          if(!pageWeb){
                              std::cout<<"problème pageweb";
                              return;
                          }
                          pageWeb->load(QUrl(settings->value(*it).toString()));
              
                          delete page;
                          delete pageWeb;
                                                                              }
                                      );
                      vboxGroupeFavorites->addWidget(checkBox);
                      delete checkBox;
                  }
              
                  groupeFavorites->setLayout(vboxGroupeFavorites);
                  dialogListeFavoris->show();
              }



              • Partager sur Facebook
              • Partager sur Twitter
                9 septembre 2017 à 14:19:16

                Pourquoi il addTab(page) puis delete page ?

                Pourquoi QWebView et mit sur le tas si c'est pour le détruire après ?

                • Partager sur Facebook
                • Partager sur Twitter
                  9 septembre 2017 à 17:09:03

                  Tu as raison.  J'ai retiré le delete page déjà.

                  Est-ce que à la sortie d'une lambda fonction, les pointeurs déclarés dans la lambda fonction, sont détruits lorsque l'on sort de cette lambda fonction ?

                  Pour le addTab, j'en ai besoin pour ajouter un nouvel onglet quand je clique sur un QCheckBox de la liste des favoris.

                  -
                  Edité par pseudo-simple 9 septembre 2017 à 17:31:44

                  • Partager sur Facebook
                  • Partager sur Twitter
                    9 septembre 2017 à 17:55:45

                    > Est-ce que à la sortie d'une lambda fonction, les pointeurs déclarés dans la lambda fonction, sont détruits lorsque l'on sort de cette lambda fonction ?

                    les pointeurs déclarés dans une fonction sont-ils détruits lorsque l'on sort de cette fonction ?

                    C'est pareil avec les lambdas.

                    Après, je suis persuadé que la question est mal posée puisque toutes variables déclarées dans un scope sont détruites à la fin de celui-ci. Il faudrait plutôt demander: "Toutes les variables allouer dynamiquement sont-elles détruites ?".

                    Et la réponse est non. C'est pour cela qu'on a les pointeurs intelligents et Qt un système de parent/enfant.

                    • Partager sur Facebook
                    • Partager sur Twitter
                      10 septembre 2017 à 17:08:10

                      Salut Jo_link_noir,

                      j'ai cherché à tenir compte de ce que tu écris, et il y a encore un bug sur les deux QObject::connect qui engendrent un bug.

                      Voici le code actuel retravaillé :

                      void FenPrincipale::ouvrirListeFavoris(){
                      
                          QStringList keys=settings->allKeys();
                      
                          for(auto it=keys.begin();it !=keys.end();it++){
                              QCheckBox *checkBox = new QCheckBox(settings->value(*it).toString(),groupeFavorites);
                      
                              checkBox->setChecked(true);
                              QObject::connect(checkBox,&QCheckBox::stateChanged,this,[=](){checkBox->hide();  });
                      
                              QObject::connect(checkBox,&QCheckBox::clicked,this,[=](){
                      
                                  QWidget *page=new QWidget;
                                  QWebView *pageWeb = new QWebView(page);
                      
                                              pageWeb->load(QUrl(settings->value(*it).toString()));
                                              ui->onglets->addTab(page,urlDefault);
                      
                                                                                      });
                      
                      
                              vboxGroupeFavorites->addWidget(checkBox);
                              
                          }
                      
                          groupeFavorites->setLayout(vboxGroupeFavorites);
                          dialogListeFavoris->show();
                      }
                      



                      • Partager sur Facebook
                      • Partager sur Twitter
                        10 septembre 2017 à 17:44:26

                        Quel bug ? Quelle conséquence ?

                        -
                        Edité par jo_link_noir 10 septembre 2017 à 17:44:39

                        • Partager sur Facebook
                        • Partager sur Twitter
                          10 septembre 2017 à 18:57:27

                          Quand je supprime le deuxième connect, le code tourne

                          Quand je le remets, lorsque je clique sur un des QCheckBox, l'application plante.

                          • Partager sur Facebook
                          • Partager sur Twitter
                            11 septembre 2017 à 11:40:40

                            ajoute un parent à page

                            d'où il sort urlDefault ?

                            je pense que ton soucis viens de ton mode de capture, tu captures tout par valeur, alors que tu souhaites agir sur l'instance actuelle, tu devrais donc capturer par référence, voire tu n'as besoin que de this (si urlDefault est une variable membre comme je le suppose)

                            • Partager sur Facebook
                            • Partager sur Twitter
                            Dream on, Dream on, Dream until your dream comes true
                              14 septembre 2017 à 21:38:53

                              urlDefault est une variable membre oui.

                              Peux-tu préciser où tu estimes que j'ai capturé par référence ? Quel est le problème en faisant cela ?

                              Quand tu parles d'instance actuelle, de quelle instance parles-tu ?

                              Merci

                              -
                              Edité par pseudo-simple 14 septembre 2017 à 22:12:10

                              • Partager sur Facebook
                              • Partager sur Twitter
                                15 septembre 2017 à 8:34:07

                                Justement, tu n'as pas capturé par référence mais par valeur dans tes fonctions lambda

                                [a,&b](params){expression} // spécifie exclusivement la capture de a par valeur et b par référence
                                [this](params){expression} // capture l'instance *this par référence
                                [&](params){expression} // capture toutes les variables par référence
                                [=](params){expression} // capture toutes les variables par valeur (copie) dont this (donc capture de *this par référence)
                                [](params){expression} // ne capture rien 

                                Le soucis, c'est qu'en capturant par valeur, tu effectue une copie locale à ta fonction lambda de toutes les variables (à portée automatique), donc lorsque tu fais une opération sur une variable, tu la fais sur une copie et pas sur l'originale.

                                Or les opérations que tu cherches à réaliser ici sont à effectuer sur this, l'instance sur laquelle cette fonction va être appelée

                                En tout cas y'a du progrès ! Enfin une joli syntaxe de connect, des déclarations auto+initialisation là où ça s'y prête bien ... c'est cool :)

                                Il manque le parent à page pour gérer la mémoire correctement et cette mécompréhension des portées/visibilités vis-à-vis des lambda mais sinon c'est pas mal.

                                Reste aussi à savoir si conceptuellement, l'utilisation d'une lambda est justifiée ici, est-ce que la fenêtre ne devrait pas proposé une fonction void ouvrirOnglet(QString url) ?

                                -
                                Edité par romantik 15 septembre 2017 à 8:36:54

                                • Partager sur Facebook
                                • Partager sur Twitter
                                Dream on, Dream on, Dream until your dream comes true
                                  15 septembre 2017 à 19:05:50

                                  Merci pour les encouragements pour les progrès effectués.    :)

                                  Pour l'état actuel du code, voici ce que j'ai fait en fonction de ce que tu conseilles (j'ai passé l'esperluette) à la place du = dans la fonction lamba

                                  J'ai mis un parent à page aussi

                                  ça plante encore :

                                  void FenPrincipale::ouvrirListeFavoris(){
                                  
                                      QStringList keys=settings->allKeys();
                                  
                                      for(auto it=keys.begin();it !=keys.end();it++){
                                          QCheckBox *checkBox = new QCheckBox(settings->value(*it).toString(),groupeFavorites);
                                  
                                          checkBox->setChecked(true);
                                   
                                  
                                          QObject::connect(checkBox,&QCheckBox::clicked,this,[&](){
                                  
                                              QWidget *page=new QWidget(ui->centralWidget);
                                              QWebView *pageWeb = new QWebView(page);
                                  
                                                          pageWeb->load(QUrl(settings->value(*it).toString()));
                                                          ui->onglets->addTab(page,urlDefault);
                                  
                                                                                                  });
                                  
                                  
                                  
                                          vboxGroupeFavorites->addWidget(checkBox);
                                        
                                      }
                                  
                                      groupeFavorites->setLayout(vboxGroupeFavorites);
                                      dialogListeFavoris->show();
                                  }
                                  



                                  -
                                  Edité par pseudo-simple 15 septembre 2017 à 19:08:41

                                  • Partager sur Facebook
                                  • Partager sur Twitter
                                    19 septembre 2017 à 19:30:50

                                    Bonjour, des idées ?

                                    -
                                    Edité par pseudo-simple 19 septembre 2017 à 19:37:35

                                    • Partager sur Facebook
                                    • Partager sur Twitter
                                      20 septembre 2017 à 14:38:51

                                      Il va falloir s'en sortir avec le débogueur pour pouvoir situer le soucis, ou bien trouver le code minimal pour pouvoir le reproduire
                                      • Partager sur Facebook
                                      • Partager sur Twitter
                                      Dream on, Dream on, Dream until your dream comes true

                                      Affichage de a liste des favoris(public 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