« Programmation Qt/Signaux et slots » : différence entre les versions

Un livre de Wikilivres.
Contenu supprimé Contenu ajouté
Aucun résumé des modifications
Aucun résumé des modifications
Ligne 6 : Ligne 6 :
== Définition ==
== Définition ==
Les signaux et slots permettent d'interconnecter des objets Qt entre eux :
Les signaux et slots permettent d'interconnecter des objets Qt entre eux :
* un '''signal''' est une valeur envoyée par un objet (<em>exemple : j'ai appuyé sur le bouton</em>) ;
* un '''signal''' est un évènement envoyé par un objet (exemple : clic de la souris sur un bouton) ;
* un '''slot''' est une fonction réalisant l'action associée à un signal.
* un '''slot''' est une fonction réalisant l'action associée à un signal.


Ligne 13 : Ligne 13 :
=== Définir un signal ===
=== Définir un signal ===


Un signal est défini dans le fichier d'en-tête déclarant la classe :

{{FichierDébut|Telechargement.h|largeur=70%|info=(extrait) Définition du signal|icon=Crystal Clear mimetype source cpp.png}}
<source lang="cpp-qt">
class Telechargement: public QObject
{
Q_OBJECT

// ...

public signals:
void fichierRecu(QString chemin_fichier);

// ...
}
</source>
{{FichierFin}}

Aucune implémentation n'est à définir dans la classe.
Le signal est utilisable dans la définition de la classe :

{{FichierDébut|Telechargement.cpp|largeur=70%|info=(extrait) Utilisation du signal|icon=Crystal Clear mimetype source cpp.png}}
<source lang="cpp-qt">
void Telechargement::Terminer()
{
// Nettoyage...
// ...
// Signaler la fin
emit fichierRecu( this->m_chemin_fichier );
}
</source>
{{FichierFin}}


=== Définir un slot ===
=== Définir un slot ===

Un slot est similaire à une méthode de la classe :
* Il doit être déclaré dans l'en-tête, dans une section <tt>slots</tt> ;
* Il doit être implémenté dans la définition de la classe.

{{FichierDébut|Stockage.h|largeur=70%|info=(extrait) Déclaration des slots|icon=Crystal Clear mimetype source h.png}}
<source lang="cpp-qt">
class Stockage: public QObject
{
Q_OBJECT

// ...

public slots:
bool stockerFichier(QString chemin_fichier);
bool supprimerFichier(QString chemin_fichier);
void finArchivage();

// ...
}
</source>
{{FichierFin}}

{{FichierDébut|Stockage.cpp|largeur=70%|info=(extrait) Définition des slots|icon=Crystal Clear mimetype source cpp.png}}
<source lang="cpp-qt">
// ...

bool Stockage::stockerFichier(QString chemin_fichier)
{
// ... copie du fichier spécifié dans le lieu de stockage
}

bool Stockage::supprimerFichier(QString chemin_fichier)
{
// ... suppression du fichier spécifié
}

void finArchivage()
{
// ... afficher le message "Fin de l'archivage"
}

// ...
</source>
{{FichierFin}}


=== Connexion ===
=== Connexion ===

Version du 24 mars 2012 à 17:17

Dans le premier exemple du chapitre précédent, cliquer sur le bouton "Hello world!" ne déclenchait aucune action. Pour qu'un bouton puisse être utile, il faut connecter le signal clicked() à un slot ayant la même signature.

Définition

Les signaux et slots permettent d'interconnecter des objets Qt entre eux :

  • un signal est un évènement envoyé par un objet (exemple : clic de la souris sur un bouton) ;
  • un slot est une fonction réalisant l'action associée à un signal.

Tout objet Qt peut définir des signaux, et des slots pour recevoir des signaux en provenance d'autres objets Qt.

Définir un signal

Un signal est défini dans le fichier d'en-tête déclarant la classe :

Telechargement.h
(extrait) Définition du signal
class Telechargement: public QObject
{
    Q_OBJECT

    // ...

public signals:
    void fichierRecu(QString chemin_fichier);

    // ...
}


Aucune implémentation n'est à définir dans la classe. Le signal est utilisable dans la définition de la classe :

Telechargement.cpp
(extrait) Utilisation du signal
void Telechargement::Terminer()
{
    // Nettoyage...
    // ...
    // Signaler la fin
    emit fichierRecu( this->m_chemin_fichier );
}


Définir un slot

Un slot est similaire à une méthode de la classe :

  • Il doit être déclaré dans l'en-tête, dans une section slots ;
  • Il doit être implémenté dans la définition de la classe.
Stockage.h
(extrait) Déclaration des slots
class Stockage: public QObject
{
    Q_OBJECT

    // ...

public slots:
    bool stockerFichier(QString chemin_fichier);
    bool supprimerFichier(QString chemin_fichier);
    void finArchivage();

    // ...
}


Stockage.cpp
(extrait) Définition des slots
// ...

bool Stockage::stockerFichier(QString chemin_fichier)
{
    // ... copie du fichier spécifié dans le lieu de stockage
}

bool Stockage::supprimerFichier(QString chemin_fichier)
{
    // ... suppression du fichier spécifié
}

void finArchivage()
{
    // ... afficher le message "Fin de l'archivage"
}

// ...


Connexion

Un signal peut être connecté :

  • à plusieurs slots : la méthode slot de l'objet est appelée quand le signal est émis ;
  • à plusieurs autres signaux : l’émission du signal provoque également l'émission de ces autres signaux.

Un slot peut recevoir plusieurs signaux, c'est à dire qu'on peut connecter le même slot à plusieurs signaux.


Utilisation

maintenant voici l'exemple:

bouton a le signal clicked() et application a le slot quit()

on connecte clicked() a quit() et quand l'utilisateur clique sur le bouton l'application se ferme.


voici connect!

connect() est une méthode statique. pour appeler une methode statique:

QObject::connect();

La méthode connect prend 4 arguments :

  • Un pointeur vers l'objet qui émet le signal
  • Le nom du signal que l'on souhaite envoyer.
  • Un pointeur vers l'objet qui contient le slot récepteur.
  • Le nom du slot qui doit s'exécuter lorsque le signal se produit.

exercice , quitter quand on appuie sur le bouton

faisons un code (mafenetre.cpp)

//main.cpp
#include <QApplication>
#include "MaFenetre.h"
 
 
int main(int argc, char *argv[])
{
    QApplication app(argc, argv);
 
    MaFenetre fenetre;
    fenetre.show();
 
    return app.exec();
}
//MaFenetre.h
#ifndef DEF_MAFENETRE
#define DEF_MAFENETRE
 
#include <QApplication>
#include <QWidget>
#include <QPushButton>
 
class MaFenetre : public QWidget // On hérite de QWidget (IMPORTANT)
{
    public:
    MaFenetre();
 
    private:
    QPushButton *m_bouton; 
};
 
#endif
#include "MaFenetre.h"
 
MaFenetre::MaFenetre() : QWidget()
{
    setFixedSize(300, 150);
 
    m_bouton = new QPushButton("Quitter", this);
    m_bouton->setFont(QFont("Comic Sans MS", 14));
    m_bouton->move(110, 50);
 
    // Connexion du clic du bouton à la fermeture de l'application
    QObject::connect(m_bouton, SIGNAL(clicked()), qApp, SLOT(quit()));
}

faite qmake , make

Testons notre code ! une fenêtre s'ouvre

Rien de bien extraordinaire à première vue. Sauf que... si vous cliquez sur le bouton "Quitter", le programme s'arrête !


Utilisation de la méthode connect() pour afficher "A propos"

On peut faire un autre essai pour se faire un peu plus la main si vous voulez.

Je vous ai parlé d'un autre slot de QApplication : aboutQt(). Je vous propose de créer un second bouton qui se chargera d'afficher la fenêtre "A propos de Qt".

voici le code:

//MaFenetre.h
#ifndef DEF_MAFENETRE
#define DEF_MAFENETRE
 
#include <QApplication>
#include <QWidget>
#include <QPushButton>
 
class MaFenetre : public QWidget // On hérite de QWidget (IMPORTANT)
{
    public:
    MaFenetre();
 
    private:
    QPushButton *m_bouton; 
    QPushButton *m_aPropos; 

};
 
#endif
#include "MaFenetre.h"
 
MaFenetre::MaFenetre() : QWidget()
{
    setFixedSize(300, 150);
 
    m_quitter = new QPushButton("Quitter", this);
    m_quitter->setFont(QFont("Comic Sans MS", 14));
    m_quitter->move(110, 50);
    QObject::connect(m_quitter, SIGNAL(clicked()), qApp, SLOT(quit()));
 
    m_aPropos = new QPushButton("A propos", this);
    m_aPropos->setFont(QFont("Comic Sans MS", 14));
    m_aPropos->move(110, 90);
    QObject::connect(m_aPropos, SIGNAL(clicked()), qApp, SLOT(aboutQt()));
}

lancer l'application

Le bouton "Quitter" ferme toujours l'application.
Quant à "A propos", il provoque l'ouverture de la fenêtre "A propos de Qt".

parametre dans le signaux et les slot

La méthode statique connect() est assez originale, vous l'avez vu. Il s'agit justement d'une des particularités de Qt que l'on ne retrouve pas dans les autres bibliothèques.

<poem>maintenant comment faire une slider bar qui quand la valeur change fait changer la valeur d'un afficher LCD?


En travauxlink={{{link}}}

Cette page est en travaux. Tant que cet avis n'aura pas disparu, veuillez en considérer le plan et le contenu encore incomplets, temporaires et sujets à caution. Si vous souhaitez participer, il vous est recommandé de consulter sa page de discussion au préalable, où des informations peuvent être données sur l'avancement des travaux.