Pour aller plus loin
Pour pouvoir créer son propre signal ou slot dans une classe, il faut que celle-ci dérive directement ou indirectement de Qobject.
Ex : nous allons faire en sorte qu'un QSlider contrôle la largeur de la fenêtre. Si le slider arrive à sa valeur maximale (600 dans notre cas), alors on émet un signal agrandissementMax et on quitte l'application.
Voici le code du fichier MaFenetre.h :
#ifndef DEF_MAFENETRE
#define DEF_MAFENETRE
#include <QApplication>
#include <QWidget>
#include <QPushButton>
#include <QLCDNumber>
#include <Qslider>
class MaFenetre : public QWidget
{
Q_OBJECT // macro à placer tout au début pour personnaliser un slot
public:
MaFenetre();
public slots:
void changerLargeur(int largeur); // nouveau slot personnalisé
signals:
void agrandissementMax();
private:
QSlider *m_slider;
};
#endif
Et le code du fichier MaFenetre.cpp :
#include "MaFenetre.h"
void MaFenetre::changerLargeur(int largeur)
{
// Le slot prend en paramètre la nouvelle largeur de la fenêtre
setFixedSize(largeur, height());
if (largeur == 600)
{
// pour envoyer un paramètre : emit monSignal(parametre1, parametre2, …);
emit agrandissementMax();
}
}
MaFenetre::MaFenetre() : QWidget()
{
setFixedSize(200, 100);
m_slider = new QSlider(Qt::Horizontal, this);
m_slider->setRange(200, 600); // le slider est limité entre 200 et 600 px
m_slider->setGeometry(10, 60, 150, 20);
QObject::connect(this, SIGNAL(agrandissementMax()), qApp, SLOT(quit()));
QObject::connect(m_slider, SIGNAL(valueChanged(int)), this, SLOT(changerLargeur(int)));
}
Le signal valueChanged(int) du QSlider doit être connecté à un slot de la fenêtre qui aura pour rôle de modifier la largeur de la fenêtre.
Comme il n'existe pas de slot changerLargeur dans la classe QWidget, nous allons devoir le créer.
La connexion se fait entre le signal valueChanged(int) de notre QSlider et le slot changerLargeur(int) de notre classe MaFenetre.
Schématiquement, on a réalisé la connexion présentée à la figure suivante :

On a ajouté une section signals. Les signaux se présentent en pratique sous forme de méthodes (comme les slots) à la différence près qu'on ne les implémente pas dans le .cpp. En effet, c'est Qt qui le fait pour nous. Si vous tentez d'implémenter un signal, vous aurez une erreur du genre « Multiple definition of… ».
- Un signal peut passer un ou plusieurs paramètres (dans notre cas, il n'en envoie aucun).
- Un signal doit toujours renvoyer void.
Pour émettre un signal, on utilise le mot-clé emit de la bibliothèque Qt qui n'existe pas en C++.
Il ne reste plus qu'à connecter le nouveau signal à un slot dans le constructeur de MaFenetre :
QObject::connect(this, SIGNAL(agrandissementMax()), qApp, SLOT(quit()));
Le schéma des signaux qu'on vient d'émettre et de connecter est présenté en figure suivante :

Dans l'ordre, voici ce qui s'est passé :
- Le signal valueChanged du slider a appelé le slot changerLargeur de la fenêtre.
- Le slot a fait ce qu'il avait à faire (changer la largeur de la fenêtre) et a vérifié que la fenêtre était arrivée à sa taille maximale. Lorsque cela a été le cas, le signal personnalisé agrandissementMax() a été émis.
- Le signal agrandissementMax() de la fenêtre était connecté au slot quit() de l'application, ce qui a provoqué la fermeture du programme.
Remarque : il arrive parfois d’obtenir une erreur du style « erreur : undefined reference to `vtable for’ » quand on utilise « signal » et « slot » via la méthode connect. Pour une raison ou une autre, le compilateur n’arrive pas à créer le ou les fichiers « .moc » nécessaire à ce mécanisme.
Pour y remédier :
- Clic droit sur le projet : « Nettoyer le projet ‘…' »
- Clic droit sur le projet : « Excécuter qmake »
- Clic droit sur le projet : « Recompiler le projet ‘…' »
Créé avec HelpNDoc Personal Edition: Transformez votre documentation d'aide en un site Web époustouflant