SLOT(), pointeur, C++ et Qt

Bonjour,

Je suis en train d’apprendre le C++ avec Qt et j’ai un soucis avec un programme que personne n’arrive à résoudre. En fait la compilation se passe bien mais j’ai une erreur d’execution : la fameuse fenêtre windows … a rencontré un problème et dois fermer …

Voici mon code


//main.cpp
#include <QApplication>
#include "fenetre.h"

int main(int argc, char*argv[])
{
    QApplication app(argc, argv);

    MaFenetre fenetre;

    fenetre.show();

    return app.exec();
}


//fenetre.h
#ifndef DEF_FENETRE
#define DEF_FENETRE


#include <QApplication>
#include <QPushButton>
#include <QGridLayout>
#include <QVBoxLayout>
#include <QFormLayout>
#include <QLineEdit>
#include <QSpinBox>
#include <QMessageBox>
#include <QLabel>

class MaFenetre:public QWidget
{
    Q_OBJECT

    public:
    MaFenetre();

    public slots:
    void messageAbout();
    void messageAide();
    void messageEnvoyer();
    void retenirNom(QString);

    private:
    QPushButton *aide;
    QPushButton *envoyer;
    QPushButton *quitter;
    QPushButton *about;
    QGridLayout *layoutBouton;

    QLineEdit *nom;
    QLineEdit *prenom;
    QSpinBox *age;
    QFormLayout *layoutCoord;

    QFormLayout *layoutPrinc;
};

#endif


//fenetre.cpp
#include "fenetre.h"

MaFenetre::MaFenetre():QWidget()
{
    setWindowTitle("Exercice avec les layouts");
    setWindowIcon(QIcon("logo.png"));

    QLabel *titre = new QLabel("<center><strong>Formulaire à remplir</strong></center>");
    QLineEdit *nom = new QLineEdit;
    QLineEdit *prenom = new QLineEdit;
    QSpinBox *age = new QSpinBox;
        age->setSuffix(" ans");
        age->setRange(18, 80);
    QFormLayout *layoutCoord = new QFormLayout;

    layoutCoord->addRow(titre);
    layoutCoord->addRow("Votre &nom : ", nom);
    layoutCoord->addRow("Votre &prénom : ", prenom);
    layoutCoord->addRow("Votre â&ge : ", age);


    QPushButton *aide = new QPushButton("aide");
    aide->setCursor(Qt::PointingHandCursor);
    aide->setToolTip("ce bouton vous affiche une aide");

    QPushButton *about = new QPushButton("a Propos");
    about->setCursor(Qt::PointingHandCursor);
    about->setToolTip("ce bouton vous affiche la personne ayant fait ce logiciel");

    QPushButton *envoyer = new QPushButton("envoyer");
    envoyer->setCursor(Qt::PointingHandCursor);
    envoyer->setToolTip("ce bouton vous permet d'envoyer vos données");
    envoyer->setEnabled(false);

    QPushButton *quitter = new QPushButton("quitter");
    quitter->setCursor(Qt::PointingHandCursor);
    quitter->setToolTip("ce bouton vous permet de fermer l'application");

    QGridLayout *layoutBouton = new QGridLayout;

    layoutBouton->addWidget(aide, 0, 0, 1, 1);
    layoutBouton->addWidget(envoyer, 0, 1, 1, 1);
    layoutBouton->addWidget(quitter, 0, 2, 1, 1);
    layoutBouton->addWidget(about, 1, 0, 1, 3);


    QFormLayout *layoutPrinc = new QFormLayout;
    layoutPrinc->addRow(layoutCoord);
    layoutPrinc->addRow(layoutBouton);

    setLayout(layoutPrinc);


    QObject::connect(aide, SIGNAL(clicked()), this, SLOT(messageAide()));
    QObject::connect(quitter, SIGNAL(clicked()), qApp, SLOT(quit()));
    QObject::connect(envoyer, SIGNAL(clicked()), this, SLOT(messageEnvoyer()));
    QObject::connect(about, SIGNAL(clicked()), this, SLOT(messageAbout()));
    QObject::connect(nom, SIGNAL(textChanged(QString)), this, SLOT(retenirNom(QString)));
}

void MaFenetre::retenirNom(QString valeurNom)
{
    if(valeurNom.length()!=0)
    {
        envoyer->setEnabled(true);
    }
    else
    {
        envoyer->setEnabled(false);
    }
}

void MaFenetre::messageAide()
{
    QMessageBox::information(this, "aide", "Il faut remplir les différents champs : <br /><strong>- nom<br />- prénom<br />- âge<br /></strong>et cliquer sur Envoyer");
}

void MaFenetre::messageEnvoyer()
{
    QMessageBox::critical(this, "envoyer", "il est actuellement impossible de stocker les informations recueillies");
}

void MaFenetre::messageAbout()
{
    QMessageBox::about(this, "a Propos", "Ce logiciel a été réalisé par<br /><strong>***</strong>");
}

cette erreur vient souvent de l’utilisation d’une zone mémoire interdite. (on pointe sur 0 ou un emplacement non réservé à l’appli)

Ce que je trouve curieux, c’est que tu n’instancies pas de classe Fenetre. (pas de fenetre = new Fenetre)?

En espérant t’aider. :hello:

Visiblement, il y a de nouvelles classes en 4.4 …

Tu as l’erreur dès le lancement de l’exe, ou quand tu sollicites un signal ?
Déjà, tu peux essayer de compiler en retirant les connect, et en ne laissant qu’un objet par layout.
Et ensuite les rajouter un par un

Sinon tu as gdb pour debugger tout cela, ça t’aidera au moins à voir où ça plante?

Je crois que je vois la faute (ou une des fautes…):

QPushButton *envoyer = new QPushButton("envoyer");

Quand tu écris ça tu crées un pointeur local sur un objet QPushButton. Le problème c’est que l’attribut de ta classe nommé aussi “envoyer” lui pointe toujours aux fraises. Et quand tu fais “envoyer->uneMethode()” cette fois-ci en utilisant ton attribut ton programme crash tout à fait normalement.

Il faudrait plutôt écrire:

envoyer = new QPushButton("envoyer");

EDIT: le problème c’est donc quand il y a un événement qui est généré.
Edité le 12/06/2008 à 16:16