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 :

Créer des slots personalisés


Sujet :

Qt

  1. #1
    Candidat au Club
    Homme Profil pro
    ingenieur genie civil
    Inscrit en
    Janvier 2013
    Messages
    2
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Sénégal

    Informations professionnelles :
    Activité : ingenieur genie civil
    Secteur : Bâtiment Travaux Publics

    Informations forums :
    Inscription : Janvier 2013
    Messages : 2
    Points : 3
    Points
    3
    Par défaut Créer des slots personalisés
    Salut,
    Je débute avec Qt et en menant un petit projet perso j'ai crée une fenêtre principale qui contient 2 sous fenêtres (disons sf1 et sf2).sf1 contient un lineedit (Integer uniquement )"LigneTexte" , un bouton "Ajouter" et un QTableWidget "Table".sf2 contient un TextEdit "ZoneTexte".je veux faire un truc du genre :

    QObject::connect(Ajouter, SIGNAL(clicked()), Table, SLOT(AjouterLigne(LigneTexte)));
    le SLOT AjouterLigne(LigneTexte) recupere le nombre dans "LigneTexte" et et ajoute autant de ligne dans "Table"
    QObject::connect(Ajouter, SIGNAL(clicked()), zoneTexte, SLOT(AfficherTexte(ZoneTexte,LigneTexte)));
    le SLOT AfficherTexte(ZoneTexte,LigneTexte) copie le contenue de "LigneTexte" et le colle dans "ZoneTexte".

    Le truc c'est que je suis dans le constructeur ma classe FenetrePrincipale et donc si je déclare des" Private SLOT" elles ne s'appliqueront qu'a la classe et non au "zoneTexte" et a "Table".

    Question 1 : ou et comment déclarer des SLOTS personnalisées pour ces classes propres a Qt?et ou mettre le code de connexion?
    Question 2 : Au cas ou j'aurais besoin de faire des connections dans le main.cpp par exemple,la structure suivante ferait-elle l'affaire?

    QObject::connect(sf1.Ajouter, SIGNAL(clicked()), Sf1.Table, SLOT(AjouterLigne(sf1.LigneTexte)));
    QObject::connect(sf1.Ajouter, SIGNAL(clicked()), sf2.zoneTexte, SLOT(AfficherTexte(sf2.ZoneTexte,sf1.LigneTexte)));

    Merci d'avance!

  2. #2
    Expert éminent sénior
    Avatar de koala01
    Homme Profil pro
    aucun
    Inscrit en
    Octobre 2004
    Messages
    11 614
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 52
    Localisation : Belgique

    Informations professionnelles :
    Activité : aucun

    Informations forums :
    Inscription : Octobre 2004
    Messages : 11 614
    Points : 30 626
    Points
    30 626
    Par défaut
    Salut,

    Lorsqu'il s'agit de créer des slots, tu dois te poser deux questions de base pour savoir à qui tu dois les donner:
    1. qui doit réagir au(x) signal(aux) qui sera(seront) émis
    2. qui a la capacité de connecter le(s) slot(s) au(x) signau(x)

    La situation la plus facile est celle dans laquelle c'est un des composant de la classe qui émet le signal et la classe elle-même qui réagit au signal émis (éventuellement en allant modifier le contenu d'un autre composant), car tu peux dés lors créer des slots privés et veiller à les connecter aux signaux adéquats de manière privée (par exemple dans le constructeur de la classe). Cela pourrait ressembler à quelque chose comme
    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
    class MaClasse : public QDialog{
        Q_OBJECT
    public:
        MaClasse(QWidget * parent = 0);
    private SLOTS :
        void onButtonClicked()
    private:
        QPushButton * button_;
        QLineEdit * line_;
    };
     
    MaClasse::MaClasse(QWidget * parent):QDialog(parent){
        button_ = new QPushButton("+1");
        line_ = new QLineEdit("0");
        /* on passe tout le reste */
        connect(button_, &QPushButton::clicked, this, &MaClasse::onButtonClicked());
    }
     
    void MaClasse::onButtonClicked(){
        bool result;
        auto value = line_.toInt(&result);
        if(result){
            ++value;
            line_.setText(QString("%1").arg(value));
        }
    }
    Toutes les autres situations nécessiteront de permettre à "quelque chose" d'accéder à "un peu plus que le stricte minimum légal". Par exemple, le bouton (buttons_ pourrait se trouver "ailleurs" que dans la fenêtre. Il pourrait alors être nécessaire de le passer en paramètre du constructeur de la classe qui deviendrait proche de
    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
    class MaClasse : public QDialog{
        Q_OBJECT
    public:
        MaClasse(QPushButton * toConnect, QWidget * parent = 0);
    private SLOTS :
        void onButtonClicked()
    private:
        QLineEdit * line_;
    };
     
    MaClasse::MaClasse(QPushButton * toConnect, QWidget * parent):QDialog(parent){
        /* on veut s'assurer que toConnect existe */
        assert(toConnect!=nullptr && "Null pointer detected");
        /* on aura supprimé du constructeur "tout ce qui a trait à button_;
         * mais pour le reste, il n'aura pas vraiment été modifié, à l'exception toutefois
         * de la ligne connect qui deviendrait
         */
        connect(toConnect_, &QPushButton::clicked, this, &MaClasse::onButtonClicked());
    }
     
    void MaClasse::onButtonClicked(){
        /* ne change pas */
    }
    Bien sur, il se peut fasse lui-même partie d'une autre classe (plus complexe) à partir de laquelle nous voudrions accéder à plusieurs widgets.

    L'idée, bien que "pas très orthodoxe" consisterait alors à placer les widgets auxquels on souhaite accéder depuis "l'extérieur" dans l'accessibilité publique, ce qui nous donnerait quelque chose proche de
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    class AutreClass : /* ici, je me fout de sa parentée, mais il faudra l'indiquer ;) */{
    public:
        QPushButton * button_;
       /* il y a peut être d'autres widgets accessibles ;) */
    };
    et notre classe de départ pourrait très bien ressembler à
    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
    class MaClasse : public QDialog{
        Q_OBJECT
    public:
        MaClasse(QPushButton * toConnect, QWidget * parent = 0);
    private SLOTS :
        void onButtonClicked()
    private:
        QLineEdit * line_;
    };
     
    MaClasse::MaClasse(AutreClasse & target, QWidget * parent):QDialog(parent){
        /* on veut s'assurer que toConnect existe */
        assert(ttarget.oConnect!=nullptr && "Null pointer detected");
        /* on aura supprimé du constructeur "tout ce qui a trait à button_;
         * mais pour le reste, il n'aura pas vraiment été modifié, à l'exception toutefois
         * de la ligne connect qui deviendrait
         */
        connect(target.toConnect_, &QPushButton::clicked, this, &MaClasse::onButtonClicked());
    }
     
    void MaClasse::onButtonClicked(){
        /* ne change pas */
    }
    Si le signal et le slot sont vraiment loin l'un de l'autre (comprends : pas du tout dans la même classe), il se peut que le seul endroit où l'on ait accès au deux soit une classe qui contiendra "un élément" au départ duquel le signal est émis et "un élément" qui dispose du slot qui doit être connecté.

    Tout en laissant aussi bien les widgets que le slot dans l'accessibilité, on peut décider de déclarer la classe qui est sensée relier les deux comme étant amie des deux éléments. Loin de briser l'encapsulation, cette technique permettrait au contraire d'avoir recours à des techniques plus "agressives" destinées à lui permettre d'accéder à des éléments qui devraient rester privés. Cela pourrait prendre une forme proche de
    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
    29
    class C1 : public /* on s'en fout */{
    private:
        QPushButton * button_; // l'émetteur du signal
        friend class MaClasse; // la classe MaClasse a exceptionnellement accès au contenu de C1
                              // et donc au signal émis par button_
    };
    class C2 : public /* on s'en fout */{
    private SLOTS:
        void onButtonClicked();
    private:
        QLineEdit * edit_; // l'émetteur du signal
        friend class MaClasse; // la classe MaClasse a exceptionnellement accès au contenu de C2
                               // et donc (principalement) au slot qu'elle devra connecter au bouton
    };
     
    class MaClasse : public /* on s'en fout */{
        Q_OBJECT
    public:
        MaClasse(QWidget * parent = 0);
    private:
       C1 * truc_; // le bouton est ici
       C2 * machin_; // le slot est ici
    };
    MaClasse::MaClasse(QWidget * parent) : /* ... */{
       truc_= new C1;
       machin_ = new C2;
       /* grâce à l'amitié, MaClasse peut aussi bien accéder à C1::button_ qu'à C2::onButtonClicked() */
       connect(truc_->button_, &QPushButton::clicked, machin_, &C2::onButtonClicked);
    }
    Enfin, il se pourrait que le slot n'ait aucun besoin d'être privé. C'est généralement "un bonne chose" qu'il le soit, mais un slot n'est jamais qu'une fonction tout à fait normale, si, bien sur, on fait abstraction du fait qu'elle est -- entre autres -- susceptible d'être connectée à un signal.

    Il pourrait même y avoir du sens à déclarer la fonction dans... l'accessibilité publique, si l'on en arrivait à se rendre compte qu'elle correspond à un service que l'on est en droit d'attendre de la part de la classe

    Au lieu de déclarer le slot private SLOTS: nous pourrions sans aucun problème le déclarer public SLOTS:

    Et, bien sur, toutes les possibilités évoquées ici ne sont que celles auxquelles j'ai pensé en à peine cinq minutes... Il n'y aurait rien d'étonnant à en trouver d'autre en cherchant un tout petit peu plus longtemps

    Tout cela pour dire qu'il y a de très nombreuses possibilités, adaptées à de très nombreuses situations spécifiques. Les deux questions dont j'ai parlées plus haut devraient déjà te permettre de dégrossir un peu le travail, mais, pour définir quelle sera la meilleure solution dans ta situation particulière, il faudrait... que nous la connaissions correctement
    A méditer: La solution la plus simple est toujours la moins compliquée
    Ce qui se conçoit bien s'énonce clairement, et les mots pour le dire vous viennent aisément. Nicolas Boileau
    Compiler Gcc sous windows avec MinGW
    Coder efficacement en C++ : dans les bacs le 17 février 2014
    mon tout nouveau blog

Discussions similaires

  1. Créer des GtkMenuItem personalisés.
    Par bertrand125 dans le forum GTK+ avec C & C++
    Réponses: 3
    Dernier message: 17/04/2015, 09h53
  2. [Qt Designer] Créer des slots / signaux perso
    Par g_barthe dans le forum PyQt
    Réponses: 1
    Dernier message: 01/05/2008, 23h32
  3. créer des objets "User" personalisés
    Par watcha2020 dans le forum Windows Serveur
    Réponses: 2
    Dernier message: 29/04/2007, 01h48
  4. DirectDraw: Créer des surfaces 256 couleurs
    Par Magus (Dave) dans le forum DirectX
    Réponses: 5
    Dernier message: 14/10/2002, 22h28
  5. [CR] Est il possible de créer des univers avec Seagate Info?
    Par Frank dans le forum SAP Crystal Reports
    Réponses: 1
    Dernier message: 27/06/2002, 15h22

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