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

Qt Discussion :

Slot dans une autre classe


Sujet :

Qt

  1. #1
    Nouveau membre du Club
    Profil pro
    Inscrit en
    Décembre 2012
    Messages
    50
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Décembre 2012
    Messages : 50
    Points : 28
    Points
    28
    Par défaut Slot dans une autre classe
    Bonjour

    Je suis en train de développé un chat avec Qt Creator et Qt Designer.

    J'ai créer une interface graphique avec Qt Designer et 2 fichier cpp : client.cpp, mainwindows.cpp

    Mon problème, c'est que je n'arrive pas à connecter un bouton de l'interface avec un slot issue d'une autre classe.

    Mon code :

    client.h
    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
    #ifndef CLIENT_H
    #define CLIENT_H
     
     
    class QTcpSocket;
     
    class client
    {
     
    public:
        client();
     
    private slots:
            void connexion();
     
    private:
           QTcpSocket *socket ;
    };
     
    #endif // CLIENT_H
    client.cpp
    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
    #include "client.h"
     
     
    client::client()
    {
    }
     
    //Connexion à 1 serveur
    void MainWindow::connexion()
    {
        QString IPHost;
        IPHost = Ui::host;
        socket->connectToHost("IPHost", "4000");
        if (!socket)
        {
            cout<<"1"<<endl;
        }
    }
    mainwindows.h
    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
    #ifndef MAINWINDOW_H
    #define MAINWINDOW_H
     
    #include <QMainWindow>
    #include <QDialog>
     
    namespace Ui
    {
    class MainWindow;
    }
     
    class MainWindow : public QMainWindow
    {
        Q_OBJECT
     
    public:
        MainWindow(QWidget *parent = 0);
        ~MainWindow();
     
    private slots:
        void fenetre_chat();
     
    private:
        void affichertexte();
        Ui::MainWindow *ui;
    };
     
    #endif // MAINWINDOW_H
    mainwindow.cpp
    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
    #include "mainwindow.h"
    #include "ui_mainwindow.h"
    #include "client.h"
     
    //Affichage de la fenêtre principale
    MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent), ui(new Ui::MainWindow)
    {
     
        ui->setupUi(this);
        //connect(ui->chat_bouton, SIGNAL(clicked()), this,  SLOT(fenetre_chat()));
        connect(ui->connexion_bouton, SIGNAL(clicked()), client, SLOT( connexion() ) );
    }
     
    MainWindow::~MainWindow()
    {
        delete ui;
    }
     
    void MainWindow::fenetre_chat()
    {
         QDialog FENChat ;
         FENChat.show();
    }
     
    void MainWindow::affichertexte()
    {
       ui->texte->setText("allo");
    }
    Je pense que l'erreur vient de la
    connect(ui->connexion_bouton, SIGNAL(clicked()), client, SLOT( connexion() ) );

    Merci de votre aide !

  2. #2
    Invité
    Invité(e)
    Par défaut
    Bonjour,

    Pense à rester cohérent dans le nom de tes classes : MainWindow avec une majuscule au début, et Client aussi.
    Et c'est justement cette confusion : client n'est pas une instance mais juste un type, qui est à l'origine de ton problème.

  3. #3
    Nouveau membre du Club
    Profil pro
    Inscrit en
    Décembre 2012
    Messages
    50
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Décembre 2012
    Messages : 50
    Points : 28
    Points
    28
    Par défaut
    J'ai mis des majuscules a la classe client

    client.h
    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
    #ifndef CLIENT_H
    #define CLIENT_H
     
     
    class QTcpSocket;
     
    class Client
    {
     
    public:
        Client();
     
    private slots:
            void connexion();
     
    private:
           QTcpSocket *socket ;
    };
     
    #endif // CLIENT_H
    client.cpp
    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
    #include "client.h"
     
     
    Client::Client()
    {
    }
     
    //Connexion à 1 serveur
    void Client::connexion()
    {
        QString IPHost;
        IPHost = Ui::host;
        socket->connectToHost("IPHost", "4000");
        if (!socket)
        {
            cout<<"1"<<endl;
        }
    }
    dans le mainwindow.cpp je laisse : connect(ui->connexion_bouton, SIGNAL(clicked()), Client, SLOT( connexion() ) );
    mais sa me met toujours la même erreur.

    Je comprends pas trop ce qu'es une instance, je n'ai développé qu'en c, c'est mon 1er programme en c++, j'ai un peu de mal :s

  4. #4
    Invité
    Invité(e)
    Par défaut
    La fonction connect() (dans l'utilisation que tu en fais) attend en 3ème argument un pointeur sur un objet Client, et non le simple type Client qui n'a rien à faire ici.
    Ainsi quelque part tu doit avoir quelque chose comme :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    Client * client = new Client(/* arguments */);
    Et c'est ce pointeur que tu rentreras :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    connect(ui->connexion_bouton, SIGNAL(clicked()), client, SLOT( connexion() ) );

  5. #5
    Nouveau membre du Club
    Profil pro
    Inscrit en
    Décembre 2012
    Messages
    50
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Décembre 2012
    Messages : 50
    Points : 28
    Points
    28
    Par défaut
    J'ai inséré ce code dans mainwindow.cpp
    Client * client = new Client(/* arguments */);
    mais j'ai une erreur :
    erreur : C2664: 'QMetaObject::Connection QObject::connect(const QObject *,const char *,const QObject *,const char *,Qt::ConnectionType)'ÿ: impossible de convertir le paramètre 3 de 'Client *' en 'const QObject *'
    Les types point‚s n'ont aucun rapport entre euxÿ; conversion n‚cessitant reinterpret_cast, cast de style C ou cast de style fonction

    Si j'ai bien compris, client n'est pas un QObject pour lui. Il faut que je declare client.h comme sa ?

    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
    #ifndef CLIENT_H
    #define CLIENT_H
    
    
    class QTcpSocket;
    
    class Client
    {
        Q_OBJECT
    
    public:
        Client();
    
    private slots:
            void connexion();
    
    private:
           QTcpSocket *socket ;
    };
    
    #endif // CLIENT_H

  6. #6
    Invité
    Invité(e)
    Par défaut
    Pour utiliser une classe dans le système de signal/slot, celle-ci doit remplir deux critères :
    • définir la macro Q_OBJECT
    • Hériter directement ou non de QObject

    Voir la FAQ pour plus de détails.

  7. #7
    Nouveau membre du Club
    Profil pro
    Inscrit en
    Décembre 2012
    Messages
    50
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Décembre 2012
    Messages : 50
    Points : 28
    Points
    28
    Par défaut
    J'ai modifié client.h pour que la classe client hérite de QObject

    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
    #ifndef CLIENT_H
    #define CLIENT_H
     
    #include <QObject>
     
    //class QTcpSocket;
     
    class Client : public QObject
    {
        Q_OBJECT
     
    public:
        Client();
     
    private slots:
            void connexion();
     
    private:
           QTcpSocket *socket ;
    };
     
    #endif // CLIENT_H
    Sa me met l'erreur
    mainwindow.obj:-1: erreur : LNK2019: symbole externe non résolu "public: __cdecl Client::Client(void)" (??0Client@@QEAA@XZ) référencé dans la fonction "public: __cdecl MainWindow::MainWindow(class QWidget *)" (??0MainWindow@@QEAA@PEAVQWidget@@@Z)
    Problème de link ?

  8. #8
    Invité
    Invité(e)
    Par défaut
    Nettoie ton projet et recompile.
    Sinon la ligne class QTcpSocket; à dé-commenter et le slot à passer en public si tu espères pouvoir l'utiliser à l'extérieur de ta classe Client.

  9. #9
    Nouveau membre du Club
    Profil pro
    Inscrit en
    Décembre 2012
    Messages
    50
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Décembre 2012
    Messages : 50
    Points : 28
    Points
    28
    Par défaut
    J'ai enlevé le code inutile, passé le slot en public, recompilé, toujours la même erreur :s

    client.h
    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
    #ifndef CLIENT_H
    #define CLIENT_H
     
    #include <QObject>
     
    class QTcpSocket;
     
    class Client : public QObject
    {
        Q_OBJECT
     
    public:
        Client();
     
    public slots:
            void connexion();
     
    private:
           QTcpSocket *socket ;
    };
     
    #endif // CLIENT_H
    mainwindow.cpp
    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
    #include "mainwindow.h"
    #include "ui_mainwindow.h"
    #include "client.h"
     
    //Affichage de la fenêtre principale
    MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent), ui(new Ui::MainWindow)
    {
     
        ui->setupUi(this);
        Client * client = new Client;
        connect(ui->connexion_bouton, SIGNAL(clicked()), client, SLOT( connexion() ) );
    }
     
    MainWindow::~MainWindow()
    {
        delete ui;
    }

  10. #10
    Invité
    Invité(e)
    Par défaut
    Tu es bien sûr d'avoir bien nettoyé ton projet avant ? Quitte à supprimer à la main les fichiers .obj générés...

    Sinon attention aux fuites de mémoire :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    Client * client = new Client;
    tel quel ton pointeur n'est jamais libéré... Selon ce que tu souhaites en faire, à voir de la passer en membre de ta classe, et le delete dans le destructeur.
    Dernière modification par Invité ; 10/03/2014 à 12h03.

  11. #11
    Nouveau membre du Club
    Profil pro
    Inscrit en
    Décembre 2012
    Messages
    50
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Décembre 2012
    Messages : 50
    Points : 28
    Points
    28
    Par défaut
    j'ai supprimé les .obj, j'ai passé client en membre de la classe. Le projet se compile ! Mais l'exe plante :s
    J'ai essayé de passer Client en membre public ou private, même résultat.

    mainwindow.h
    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
    #ifndef MAINWINDOW_H
    #define MAINWINDOW_H
     
    #include <QMainWindow>
    #include <QDialog>
    #include "client.h"
     
    namespace Ui
    {
    class MainWindow;
    }
     
    class MainWindow : public QMainWindow
    {
        Q_OBJECT
     
    public:
        MainWindow(QWidget *parent = 0);
        ~MainWindow();
        Client *lancer_client;
    private:
        Ui::MainWindow *ui;
     
    };
     
    #endif // MAINWINDOW_H
    mainwindow.cpp
    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
    #include "mainwindow.h"
    #include "ui_mainwindow.h"
    #include "client.h"
     
    //Affichage de la fenêtre principale
    MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent), ui(new Ui::MainWindow)
    {
     
        ui->setupUi(this);
     
        connect(ui->connexion_bouton, SIGNAL(clicked()), lancer_client, SLOT( connexion() ) );
    }
     
    MainWindow::~MainWindow()
    {
        delete ui;
    }

  12. #12
    Invité
    Invité(e)
    Par défaut
    Tu as oublié d'initialiser (new) ton pointeur, sans oublier comme dit sa libération (delete) dans le destructeur.

  13. #13
    Nouveau membre du Club
    Profil pro
    Inscrit en
    Décembre 2012
    Messages
    50
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Décembre 2012
    Messages : 50
    Points : 28
    Points
    28
    Par défaut
    Je sais pas trop si c'est comme sa qu'on initialise avec new, j'ai regarder http://chgi.developpez.com/pointeur/

    mainwindow.cpp
    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
    #include "mainwindow.h"
    #include "ui_mainwindow.h"
    #include "client.h"
     
    //Affichage de la fenêtre principale
    MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent), ui(new Ui::MainWindow)
    {
     
        ui->setupUi(this);
        Client *lancer_client = new Client ;
        connect(ui->connexion_bouton, SIGNAL(clicked()), lancer_client, SLOT( connexion() ) );
    }
     
    MainWindow::~MainWindow()
    {
        delete ui;
        delete lancer_client;
    }

  14. #14
    Invité
    Invité(e)
    Par défaut
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    Client *lancer_client = new Client ;
    sinon tu crées une variable locale au constructeur qui n'a absolument rien à voir avec le membre du même nom.
    Tu peux aussi le placer dans la liste d'initialisation comme tu as fait pour ui

  15. #15
    Nouveau membre du Club
    Profil pro
    Inscrit en
    Décembre 2012
    Messages
    50
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Décembre 2012
    Messages : 50
    Points : 28
    Points
    28
    Par défaut
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    lancer_client = new Client ;
    ne fonctionne pas, sa me met toujours la même erreur :s

    si je le met dans la liste d'initialisation, sa ne marche pas non plus :s

    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
    #include "mainwindow.h"
    #include "ui_mainwindow.h"
    #include "client.h"
     
    //Affichage de la fenêtre principale
    MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent), ui(new Ui::MainWindow), lancer_client(new Client)
    {
     
        ui->setupUi(this);
        connect(ui->connexion_bouton, SIGNAL(clicked()), lancer_client, SLOT( connexion() ) );
    }
     
    MainWindow::~MainWindow()
    {
        delete ui;
        delete lancer_client;
    }

  16. #16
    Invité
    Invité(e)
    Par défaut
    Messages d'erreur stp. Tu le déclares bien en membre de la classe ?

  17. #17
    Nouveau membre du Club
    Profil pro
    Inscrit en
    Décembre 2012
    Messages
    50
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Décembre 2012
    Messages : 50
    Points : 28
    Points
    28
    Par défaut
    oui je le declare comme sa :

    mainwindow.h
    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
    #ifndef MAINWINDOW_H
    #define MAINWINDOW_H
     
    #include <QMainWindow>
    #include <QDialog>
    #include "client.h"
     
    namespace Ui
    {
    class MainWindow;
    }
     
    class MainWindow : public QMainWindow
    {
        Q_OBJECT
     
    public:
        MainWindow(QWidget *parent = 0);
        ~MainWindow();
        Client *lancer_client;
     
    private:
        Ui::MainWindow *ui;
     
    };
     
    #endif // MAINWINDOW_H
    Le message d'erreur que sa me met :
    mainwindow.obj:-1: erreur : LNK2019: symbole externe non résolu "public: __cdecl Client::Client(void)" (??0Client@@QEAA@XZ) référencé dans la fonction "public: __cdecl MainWindow::MainWindow(class QWidget *)" (??0MainWindow@@QEAA@PEAVQWidget@@@Z)

  18. #18
    Invité
    Invité(e)
    Par défaut
    C'est de nouveau la même erreur que précédemment, donc si tenté que tu aies laissé la définition de
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    Client::Client()
    {
    }
    il n'y a aucune raison d'obtenir cette erreur... et un nettoyage du projet règlera de nouveau l'affaire.

  19. #19
    Nouveau membre du Club
    Profil pro
    Inscrit en
    Décembre 2012
    Messages
    50
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Décembre 2012
    Messages : 50
    Points : 28
    Points
    28
    Par défaut
    J'ai fait 1 nettoyage total, supprimé les .obj, j'ai toujours la même erreur :s
    La définition de Client est dans client.cpp

    client.h
    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
    #ifndef CLIENT_H
    #define CLIENT_H
     
    #include <QObject>
    #include <QtNetwork/QTcpSocket>
     
     
    class Client : public QObject
    {
        Q_OBJECT
     
    public:
        Client();
     
    public slots:
            void connexion();
     
    private:
           QTcpSocket *socket ;
    };
     
    #endif // CLIENT_H
    client.cpp
    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
    #include "client.h"
     
     
    Client::Client()
    {
    }
     
    //Connexion à 1 serveur
    void Client::connexion()
    {
        QString IPHost;
        IPHost = Ui::host;
        socket->connectToHost("IPHost", "4000");
        if (!socket)
        {
            cout<<"1"<<endl;
        }
    }
    mainwindow.h
    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
    #ifndef MAINWINDOW_H
    #define MAINWINDOW_H
     
    #include <QMainWindow>
    #include <QDialog>
    #include "client.h"
     
    namespace Ui
    {
    class MainWindow;
    }
     
    class MainWindow : public QMainWindow
    {
        Q_OBJECT
     
    public:
        MainWindow(QWidget *parent = 0);
        ~MainWindow();
        Client *lancer_client;
     
    private:
        Ui::MainWindow *ui;
     
    };
     
    #endif // MAINWINDOW_H
    mainwindow.cpp
    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
    #include "mainwindow.h"
    #include "ui_mainwindow.h"
    #include "client.h"
     
    //Affichage de la fenêtre principale
    MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent), ui(new Ui::MainWindow)
    {
     
        ui->setupUi(this);
        lancer_client = new Client;
        connect(ui->connexion_bouton, SIGNAL(clicked()), lancer_client, SLOT( connexion() ) );
    }
     
    MainWindow::~MainWindow()
    {
        delete ui;
        delete lancer_client;
    }

  20. #20
    Nouveau membre du Club
    Profil pro
    Inscrit en
    Décembre 2012
    Messages
    50
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Décembre 2012
    Messages : 50
    Points : 28
    Points
    28
    Par défaut
    Je viens de trouver !
    En fait j'ai oublié de faire un coup de qmake après le nettoyage.
    Mon application se compile et s’exécute !
    Merci de ton aide, je vais attaquer le serveur maintenant ! Je passe le sujet en résolue

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. Définir une classe dans une autre classe
    Par acieroid dans le forum C++
    Réponses: 7
    Dernier message: 22/05/2006, 00h24
  2. Probleme d'apel de fonction dans une autre classe
    Par freecell31 dans le forum MFC
    Réponses: 24
    Dernier message: 13/05/2006, 12h34
  3. Réponses: 1
    Dernier message: 05/05/2006, 15h37
  4. Acceder à un object qui se trouve dans une autre classe
    Par ceres02 dans le forum AWT/Swing
    Réponses: 8
    Dernier message: 08/02/2006, 14h29
  5. Réponses: 12
    Dernier message: 11/11/2005, 15h25

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