Partage
  • Partager sur Facebook
  • Partager sur Twitter

qt probleme de slot

Sujet résolu
    25 mai 2020 à 15:45:58

    bonjour

    j'ai un QCheckbox pour activer une zone de texte (un  QLineEdit)

    mais voila on code:

        connect(
            motDePasseQestion,
            &QCheckBox::stateChanged,
            this,
            &FenServeur::taperCode
        );
    }
    
    void FenServeur::taperCode()
    {
        if (motDePasseQestion->isChecked())
        {
            etatServeur->setText("ca marche");
            leMotDePasse->setEnabled(true);
        }
        else
        {
            etatServeur->setText("ou pas");
            leMotDePasse->setEnabled(false);
        }
    }

    ca ne marche pas la fonction ne se lance même pas  et je ne compend pas mon erreur merci de m'aidé

    merci d'avance

    -
    Edité par unel 25 mai 2020 à 15:59:30

    • Partager sur Facebook
    • Partager sur Twitter
      25 mai 2020 à 17:07:33

      Salut ! Une erreur de segmentation c’est un mauvais accès à la mémoire. Vérifie qu‘un de tes pointeurs ne pointe pas vers 0x0, que tu manipules tes pointeurs comme il faut.

      Pour voir approximativement ou ton  programme foire tu peux laisser une trace à chaque étape du code, avec des affichages dans le terminal. Si tu veux précisément savoir ce qui pose problème tu debug ton programme (en oubliant pas de compiler en mode déboggage).

      -
      Edité par Daimyo_ 25 mai 2020 à 17:12:30

      • Partager sur Facebook
      • Partager sur Twitter
        25 mai 2020 à 17:13:19

        jais déjà vérifier et non

        mais ca me fait ca a chaque connexion

        • Partager sur Facebook
        • Partager sur Twitter
          25 mai 2020 à 17:17:30

          Tu as déboggué ton programme ? Ton erreur vient pas de nulle part, c’est forcément un problème de gestion de mémoire.

          Donc tu as un signal d’erreur de segmentation lors de la connexion. Ça veut dire que ça vient d’ici.

          -
          Edité par Daimyo_ 25 mai 2020 à 17:20:17

          • Partager sur Facebook
          • Partager sur Twitter
            26 mai 2020 à 11:25:00

            bonjour voici mon code mais moi je ne vois nul par un pointeur qui ne pointe pas ou d'autre erreur et non le compilateur ne dit rien

            #include "FenServeur.h"
            #include <QSpinBox>
            #include <QTableWidget>
            #include <QFile>
            #include <QString>
            #include <QDataStream>
            #include <QTextStream>
            #include <QIODevice>
            #include <QHostAddress>
            FenServeur::FenServeur()
            {
            
                setWindowTitle(tr("ANANTA SYSTEME TCHAT - Serveur"));
                QVBoxLayout *layout = new QVBoxLayout(this);
                QTabWidget *onglets = new QTabWidget();
                QWidget *general = new QWidget;
                QWidget *avancee = new QWidget;
            
                //ouvertur des flux
                // Création et disposition des widgets de la fenêtre
                //page 1
                etatServeur = new QTextEdit;
                etatServeur->isReadOnly();
                etatServeur->setTextInteractionFlags(Qt::TextSelectableByMouse);
                etatServeur->setCursor(Qt::IBeamCursor);
                boutonQuitter = new QPushButton(tr("Quitter et deconecter le chat pour tout le(s) client(s)"));
                connect(boutonQuitter, SIGNAL(clicked()), qApp, SLOT(quit()));
            
                messagesup = new QTextEdit;
                messagesup->setTextInteractionFlags(Qt::TextSelectableByMouse);
                messagesup->setCursor(Qt::IBeamCursor);
                messagesup->isReadOnly();
            
                QGridLayout *page1 = new QGridLayout;
                page1->addWidget(etatServeur, 0,0,0,1);
                page1->addWidget(boutonQuitter,0,1);
                page1->addWidget(messagesup,1,1);
                setLayout(page1);
                general->setLayout(page1);
                layout->addWidget(onglets);
            
                onglets->addTab(general, "general");
            
                //page 2
            
                QCheckBox *motDePasseQestion = new QCheckBox("demander un mot de passe pour rejoidre ?");
            
                QLineEdit *leMotDePasse = new QLineEdit("mot de passe");
                leMotDePasse->setEchoMode(QLineEdit::Password);
                leMotDePasse->setEnabled(false);
                QCheckBox *enregistrerFicherQuestion = new QCheckBox("enregistrer dans un fichier ?");
                enregistrerFicherQuestion->setChecked(true);
                QCheckBox *envoyerDiscutionQuestion = new QCheckBox("envoyer la discution aux nouveaux client ?");
                envoyerDiscutionQuestion->setChecked(true);
                QPushButton *changerDePort = new QPushButton("changer de port");
                connect(
                    changerDePort,
                    &QPushButton::clicked,
                    this,
                    &FenServeur::changerPort
                );
                QPushButton *effacerDiscution = new QPushButton("efacer la discution");
                //disposition
                QGridLayout *page2 = new QGridLayout;
                page2->addWidget(motDePasseQestion, 0,0);
                page2->addWidget(leMotDePasse, 0,1);
                page2->addWidget(enregistrerFicherQuestion, 1,0);
                page2->addWidget(envoyerDiscutionQuestion,2,0);
                page2->addWidget(changerDePort,3,0);
                page2->addWidget(effacerDiscution,4,0);
            
                avancee->setLayout(page2);
                layout->addWidget(onglets);
                onglets->addTab(avancee, "avancée");
            
                // Gestion du serveur
                  serveur = new QTcpServer(this);
                  if (!serveur->listen(QHostAddress::Any)) // Démarrage du serveur sur toutes les IP disponibles et sur le port
                  {
                      // Si le serveur n'a pas été démarré correctement
                      etatServeur->setText(tr("Le serveur n'a pas pu être démarré. Raison :<br />") + serveur->errorString() + tr(" atention a bien deconecter tout les vpn et par-feux"));
            
                  }
                  else
                  {
                      // Si le serveur a été démarré correctement
                      etatServeur->setText(tr("Le serveur a été démarré sur le port <strong>") + QString::number(serveur->serverPort()) + tr("</strong>.<br />Des clients peuvent maintenant se connecter."));
                      connect(serveur, SIGNAL(newConnection()), this, SLOT(nouvelleConnexion()));
            
                  }
                  tailleMessage = 0;
            
            
            
                //on met tout dans le messagesup
                QHostAddress host(QHostAddress::LocalHost);
                QString ipv4 = host.toString();
                QString localhostname =  QHostInfo::localHostName();
                QString localhostIP;
                QString localhostIPv6;
                QList<QHostAddress> hostList = QHostInfo::fromName(localhostname).addresses();
                foreach (const QHostAddress& address, hostList) {
                    if (address.protocol() == QAbstractSocket::IPv4Protocol && address.isLoopback() == false) {
                         localhostIP = address.toString();
                    }
                    else
                    {
                        localhostIP = "aucune adresse trouvée deconecter les VPN";
                    }
                    if (address.protocol() == QAbstractSocket::IPv6Protocol && address.isLoopback() == false) {
                         localhostIPv6 = address.toString();
                    }
                    else
                    {
                        localhostIPv6 = "aucune adresse trouvée deconecter les VPN";
                    }
                }
                QString localMacAddress;
                QString localNetmask;
                foreach (const QNetworkInterface& networkInterface, QNetworkInterface::allInterfaces()) {
                    foreach (const QNetworkAddressEntry& entry, networkInterface.addressEntries()) {
                        if (entry.ip().toString() == localhostIP) {
                            localMacAddress = networkInterface.hardwareAddress();
                            localNetmask = entry.netmask().toString();
                            break;
                        }
                    }
                }
            
                qDebug() << "Localhost name: " << localhostname;
                qDebug() << "IP = " << localhostIP;
                qDebug() << "MAC = " << localMacAddress;
                qDebug() << "Netmask = " << localNetmask;
                messagesup->setText(tr("merci d’avoir télécharger Ananta système chat ! <br /> info utile <br /> votre adresse ip interne est <strong>") + ipv4 + tr("</strong> <br /> votre adresse ip v4 est:  <strong>") + localhostIP + tr("</strong> <br /> votre adresse ip v6 est:  <strong>") + localhostIPv6 + tr("</strong> <br /> votre adressse mac est: <strong>") + localMacAddress + tr("</strong> <br /> votre Masque de sous-réseau est : <strong>") + localNetmask + tr("</strong> <br /> le nom de votre machine est:  <strong>") + localhostname);
                connect(
                    motDePasseQestion,
                    &QCheckBox::stateChanged,
                    this,
                    &FenServeur::taperCode
                );
            }
            void FenServeur::changerPort()
            {
                envoyerATous("<br /><em>le serveur a demadée un changement de port</em><br />");
                int reponse = QMessageBox::warning(this, "serveur confirmation changement de port", "tout les client vont etre deconectée <br> vous confirmé(e)(s)?", QMessageBox ::Yes | QMessageBox::No);
                if (reponse == QMessageBox::Yes)
                {
                    int reponse2 = QMessageBox::question(this, "serveur envoyer un message", "voulez vous que les clients soit informée du nouveaux port avant la deconexion ?", QMessageBox ::Yes | QMessageBox::No);
                    reservationDunPort = new QTcpServer(this);
                    if (!reservationDunPort->listen(QHostAddress::Any)) // Démarrage du serveur sur toutes les IP disponibles
                         {
                             // Si le serveur n'a pas été démarré correctement
                             etatServeur->setText(tr("erreur imposible de crée le nouveaux serveur.les client ne sont pas deconecter de l'encien Raison :<br />") + serveur->errorString());
                             envoyerATous("</em>erreur imposible de crée le nouveaux serveur.les client ne sont pas deconecter de l'encien la demande de changement de port n'a pas pu aboutire </em>");
                             QMessageBox::critical(this, "oups", "ca na pas fonctionéeles client ne sont pas deconecter de l'encien serveur");
                             return;
                         }
                         else
                         {
                             // Si le serveur a été démarré correctement
                             etatServeur->setText(tr("Le nouveaux serveur est pret a etre démarré sur le port <strong>") + QString::number(reservationDunPort->serverPort()));
            
                             QString aEnvoyer ("le serveur va changer sont port de conexion par : " + QString::number(reservationDunPort->serverPort()));
                             if (reponse2 == QMessageBox::Yes)
                             {
                                 envoyerATous(aEnvoyer);
                             }
                             QString leProchainPort (QString::number(reservationDunPort->serverPort()));
            
            
                             bool ok = false;
            
                             int port = leProchainPort.toInt(&ok, 10);
            
                             if( ok )
                             {
                                 etatServeur->setText("convertion du port OK");
                                 serveur->close();
            
                                 serveur = new QTcpServer(this);
                                 if (!serveur->listen(QHostAddress::Any, port)) // Démarrage du serveur sur toutes les IP disponibles et sur le port port
                                 {
                                     // Si le serveur n'a pas été démarré correctement
                                     etatServeur->setText(tr("Le serveur n'a pas pu être démarré. Raison :<br />") + serveur->errorString());
                                     QMessageBox::critical(this, "oups", "ca na pas fonctionée et les client sondeconecter pendznt la fase critique");
                                 }
                                 else
                                 {
                                     // Si le serveur a été démarré correctement
                                     etatServeur->setText(tr("Le serveur a été démarré sur le port <strong>") + QString::number(serveur->serverPort()) + tr("</strong>.<br />Des clients peuvent maintenant se connecter."));
                                     connect(serveur, SIGNAL(newConnection()), this, SLOT(nouvelleConnexion()));
                                     QMessageBox::information(this, "youpi", "tout a bien fonctionée");
                                 }
            
            
                             }
                             else
                             {
                                 etatServeur->setText("convertion du port erreur");
                                etatServeur->setText(tr("erreur imposible de crée le nouveaux serveur.les client ne sont pas deconecter de l'encien"));
                                QMessageBox::critical(this, "oups", "ca na pas fonctionéeles client ne sont pas deconecter de l'encien serveur");
                                return;
                             }
            
                         }
            
            
            
            
                }
            }
            void FenServeur::taperCode()
            {
                if (motDePasseQestion->isChecked())
                {
                    etatServeur->setText("ca marche");
                    leMotDePasse->setEnabled(true);
                }
                else
                {
                    etatServeur->setText("ou pas");
                    leMotDePasse->setEnabled(false);
                }
            }
            
            void FenServeur::nouvelleConnexion()
            {
                QString texte;
            
                envoyerATous(tr("<br /><em>Un nouveau client vient de se connecter</em><br /><br />"));
            
                QTcpSocket *nouveauClient = serveur->nextPendingConnection();
                clients << nouveauClient;
            
            
            
            
                connect(nouveauClient, SIGNAL(readyRead()), this, SLOT(donneesRecues()));
                connect(nouveauClient, SIGNAL(disconnected()), this, SLOT(deconnexionClient()));
                if (envoyerDiscutionQuestion->isChecked())
                {
                    QFile fichierLecture("chat.ants");
                    if(fichierLecture.open(QIODevice::ReadOnly | QIODevice::Text))
                    {
                         texte = fichierLecture.readAll();
                         fichierLecture.close();
                         QByteArray paquet;
                         QDataStream out(&paquet, QIODevice::ReadWrite);
            
                         out << (quint16) 0; // On écrit 0 au début du paquet pour réserver la place pour écrire la taille
                         out << texte; // On ajoute le message à la suite
                         out.device()->seek(0); // On se replace au début du paquet
                         out << (quint16) (paquet.size() - sizeof(quint16)); // On écrase le 0 qu'on avait réservé par la longueur du message
                         int dernierClient(clients.size()-1);
                         clients[dernierClient]->write(paquet);
                    }
                    else etatServeur->setText("Impossible d'ouvrir le fichier !");
                }
            
            
            
            
            }
            
            
            void FenServeur::donneesRecues()
            {
                // 1 : on reçoit un paquet (ou un sous-paquet) d'un des clients
            
                // On détermine quel client envoie le message (recherche du QTcpSocket du client)
                QTcpSocket *socket = qobject_cast<QTcpSocket *>(sender());
                if (socket == 0) // Si par hasard on n'a pas trouvé le client à l'origine du signal, on arrête la méthode
                    return;
            
                // Si tout va bien, on continue : on récupère le message
                QDataStream in(socket);
            
                if (tailleMessage == 0) // Si on ne connaît pas encore la taille du message, on essaie de la récupérer
                {
                    if (socket->bytesAvailable() < (int)sizeof(quint16)) // On n'a pas reçu la taille du message en entier
                         return;
            
                    in >> tailleMessage; // Si on a reçu la taille du message en entier, on la récupère
                }
            
                // Si on connaît la taille du message, on vérifie si on a reçu le message en entier
                if (socket->bytesAvailable() < tailleMessage) // Si on n'a pas encore tout reçu, on arrête la méthode
                    return;
            
            
                // Si ces lignes s'exécutent, c'est qu'on a reçu tout le message : on peut le récupérer !
                QString message;
                in >> message;
            
            
                // 2 : on renvoie le message à tous les clients
                envoyerATous(message);
            
                // 3 : remise de la taille du message à 0 pour permettre la réception des futurs messages
                tailleMessage = 0;
            }
            
            void FenServeur::deconnexionClient()
            {
                envoyerATous(tr("<em>Un client vient de se déconnecter</em>"));
            
                // On détermine quel client se déconnecte
                QTcpSocket *socket = qobject_cast<QTcpSocket *>(sender());
                if (socket == 0) // Si par hasard on n'a pas trouvé le client à l'origine du signal, on arrête la méthode
                    return;
            
                clients.removeOne(socket);
            
                socket->deleteLater();
            }
            
            void FenServeur::envoyerATous(const QString &message)
            {
                if (enregistrerFicherQuestion->isChecked())
                {
                    QString nom("chat.ants");
                    QFile file(nom);
                    if (file.open(QIODevice::ReadWrite | QIODevice::Text | QIODevice::Append))
                    {
                        QTextStream fichier(&file);
                        fichier.setCodec("UTF-8");
                        fichier << message;
                    }
                    else
                    {
                        etatServeur->setText(tr("il est imposible d'ecrire dans le fichier"));
                    }
                    file.close();
                }
            
                // Préparation du paquet
                QByteArray paquet;
                QDataStream out(&paquet, QIODevice::ReadWrite);
            
                out << (quint16) 0; // On écrit 0 au début du paquet pour réserver la place pour écrire la taille
                out << message; // On ajoute le message à la suite
                out.device()->seek(0); // On se replace au début du paquet
                out << (quint16) (paquet.size() - sizeof(quint16)); // On écrase le 0 qu'on avait réservé par la longueur du message
            
            
            
            
                // Envoi du paquet préparé à tous les clients connectés au serveur
                for (int i = 0; i < clients.size(); i++)
                {
                    clients[i]->write(paquet);
                }
            
            
            
            }
            
            

            en changent de compilo ca done ca :

            • Partager sur Facebook
            • Partager sur Twitter
              26 mai 2020 à 13:43:58

              Un débogueur n'est pas un compilateur. Ton débogueur sert à garder une trace de l'état de ton environnement d'exécution lorsque tu exécutes l'application.

              Essaie de placer des points d'arrêt aux endroits clé de ton programme, au début de ta fonction membre taperCode etc. Après avoir placé des points d'arrêt, tu exécutes ton code (Debug mode: avec l'insecte sur le bouton d'exécution), tu remarqueras qu'à chaque point d'arrêt placé, l'exécution du programme sera en "pause". Au bout d'un moment, tu trouveras un endroit ou l'exécution s'arrête violemment, et tu auras un message qui dit qu'il y a une erreur de segmentation. Ton débogueur te permettra de te fournir précisément la source du signal SIGSEV.

              Encore une fois, un signal d'erreur de segmentation vient d'un problème d'accès à la mémoire via des pointeurs ! D'après le message d'erreur que tu obtiens, il y a "flags=0x0" qui m'interpelle, ça me fait penser que la source du signal vient d'un pointeur sur 0x0 (ou nullptr; dans les deux cas ça pointe sur une adresse invalide), mais je suis pas certain. Vérifie que tous tes pointeurs sont bien initialisés avec une adresse valide.

              Et, j'ai juste une question, pourquoi autant de pointeurs ?? Je n'utilise pas Qt, donc il se pourrait que ça soit une "norme" lorsqu'on utilise le framework, mais si ça n'est pas le cas, je te conseille de ne pas utiliser autant de pointeurs nus, sinon tu te retrouves devant la fameuse erreur de segmentation et ça peut aller beaucoup plus loin.

              -
              Edité par Daimyo_ 26 mai 2020 à 13:53:24

              • Partager sur Facebook
              • Partager sur Twitter
              Anonyme
                26 mai 2020 à 14:29:33

                Daimyo_ a écrit:

                Et, j'ai juste une question, pourquoi autant de pointeurs ?? Je n'utilise pas Qt, donc il se pourrait que ça soit une "norme" lorsqu'on utilise le framework, mais si ça n'est pas le cas, je te conseille de ne pas utiliser autant de pointeurs nus, sinon tu te retrouves devant la fameuse erreur de segmentation et ça peut aller beaucoup plus loin.

                -
                Edité par Daimyo_ il y a 29 minutes


                C'est la norme avec Qt, au moins tant qu'on n'aura pas Qt6. Je crois qu'à partir de là, ils vont mieux intégrer les évolutions de C++. Qt5 est sorti en fin 2012, donc ils ont pu spécifier la base avant que la norme C++11 soit définitive, d'où certains archaïsmes. Cependant, Qt intègre un système de gestion de mémoire entre QObject (la classe de base des objets Qt).

                Par contre, il convient de donner le QObject parent sinon ça complique les choses (pour un élément d'UI, ça dépend de l'élément conteneur dans lequel il se trouve). Grosso modo, quand le parent est supprimé, ses enfants le sont avec (c'est plus compliqué que ça dans les faits).

                Il est d'ailleurs déconseillé d'utiliser les pointeurs intelligents sur des classes dérivant de QObject. On peut bien sûr utiliser des std::unique_ptr<> sur des classes personnelles qui ne dérivent pas de QObject (c'est ce que je fais personnellement) puisque celles-ci ne dépendent pas du "garbage collector" de Qt.

                ____

                Pour ton code, tu devrais passer par QtDesigner. L'UI codée ainsi c'est indigeste...

                Pour ton crash, c'est ce qu'on appelle du variable shadowing... En gros, tu déclares des variables dans ton constructeur qui ont le même nom que tes données membres, le tout précédé du type. C++ crée de nouveaux objets locaux mais ton pointeur "motDePasseQestion" appartenant à ta classe fenêtre reste nul.

                https://en.wikipedia.org/wiki/Variable_shadowing

                -
                Edité par Anonyme 26 mai 2020 à 14:48:25

                • Partager sur Facebook
                • Partager sur Twitter
                  26 mai 2020 à 17:49:07

                  AntiXeon a écrit:

                  C'est la norme avec Qt, au moins tant qu'on n'aura pas Qt6. Je crois qu'à partir de là, ils vont mieux intégrer les évolutions de C++. Qt5 est sorti en fin 2012, donc ils ont pu spécifier la base avant que la norme C++11 soit définitive, d'où certains archaïsmes. Cependant, Qt intègre un système de gestion de mémoire entre QObject (la classe de base des objets Qt).

                  Je n'ai pas le souvenir que ce point sera changé dans Qt6. J'ai peut être loupé un truc, mais je crois que la rétro-compatibilité du code est assurée donc le système parent-enfants ne sera pas supprimé.

                  • Partager sur Facebook
                  • Partager sur Twitter
                    26 mai 2020 à 18:47:01

                    heu les point d'arrêt ca ne marche pas : 

                    *peut etre qu je vais le faire en ui donc

                    -
                    Edité par unel 26 mai 2020 à 18:50:42

                    • Partager sur Facebook
                    • Partager sur Twitter
                    Anonyme
                      26 mai 2020 à 22:56:48

                      gbdivers a écrit:

                      AntiXeon a écrit:

                      C'est la norme avec Qt, au moins tant qu'on n'aura pas Qt6. Je crois qu'à partir de là, ils vont mieux intégrer les évolutions de C++. Qt5 est sorti en fin 2012, donc ils ont pu spécifier la base avant que la norme C++11 soit définitive, d'où certains archaïsmes. Cependant, Qt intègre un système de gestion de mémoire entre QObject (la classe de base des objets Qt).

                      Je n'ai pas le souvenir que ce point sera changé dans Qt6. J'ai peut être loupé un truc, mais je crois que la rétro-compatibilité du code est assurée donc le système parent-enfants ne sera pas supprimé.

                      Oui, je me suis très mal exprimé (je pensais que le "au moins" suffirait). Je voulais juste dire que Qt6 allait se baser sur C++17 (en interne). Pour les évolutions que ça va apporter concernant la gestion de la mémoire, à voir s'ils introduiront de nouvelles choses en plus du système parent-enfant... On ne sait jamais, même si c'est peu probable.

                      Pour le crash, je le redis autrement si ce n'était pas clair : tu as vraisemblablement des données membres dans ton .h (si j'en juge ton slot "taperCode()"). Or, tu déclares de nouvelles variables localement dans ton constructeur qui portent le même nom. Ça, ça t'induit complètement en erreur car tu crois instancier ta donnée membre mais en réalité il n'en est rien.

                      Une convention pour les données membres est de mettre un préfixe comme "_" ou "m_". Par exemple, dans le .h :

                      QCheckBox *m_motDePasseQestion = nullptr;

                      Puis, dans le .cpp, tu fais :

                      m_motDePasseQestion = new QCheckBox();

                      Et là, ta checkbox sera bien initialisée, donc le pointeur sera non nul...
                      Et il en va de même pour toutes tes données membres, sinon tu ne feras que reproduire le crash pour d'autres données.

                      Tu peux bien entendu refaire ça avec un .ui. C'est à mon avis beaucoup mieux car c'est visuel, plus facile à gérer et ça t'évite les trucs hyper chiants comme la gestion des layouts. Mais si tu ne comprends pas ce que j'essaie de t'expliquer concernant ton crash, le problème se répètera encore.

                      • Partager sur Facebook
                      • Partager sur Twitter

                      qt probleme de 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