Cours:SignalSlotQT : Différence entre versions
(→clignotement avec QTimer) |
(→principe) |
||
Ligne 83 : | Ligne 83 : | ||
Nous avons précédemment fait cette connexion graphiquement dans qtDesigner, ici nous allons utiliser la fonction {{Rouge|connect}}. | Nous avons précédemment fait cette connexion graphiquement dans qtDesigner, ici nous allons utiliser la fonction {{Rouge|connect}}. | ||
<source lang=cpp> | <source lang=cpp> | ||
− | connect(&objetEmetteur, | + | connect(&objetEmetteur,&ClasseObjetEmetteur::signalEmis,&objetRecepteur,&ClasseObjetRecepteur::slotToExecute); |
</source> | </source> | ||
Ligne 95 : | Ligne 95 : | ||
// on ajoute ici les connexions | // on ajoute ici les connexions | ||
// objet vers mainwindow | // objet vers mainwindow | ||
− | connect(& | + | connect(&obj,&ClasseObjetEmetteur::signalEmis,this,&MainWindow::monSlot); |
// mainwindow vers objet | // mainwindow vers objet | ||
− | connect(this, | + | connect(this,&MainWindow::monSignal,&obj,&ClasseObjetRecepteur::slotToExecute); |
// ou d'un objet graphique vers un objet de la nouvelle classe | // ou d'un objet graphique vers un objet de la nouvelle classe | ||
− | connect(ui->pushButton, | + | connect(ui->pushButton,&ClasseObjetRecepteur::signalEmis,&obj,&ClasseObjetRecepteur::nomDuSlot); |
} | } | ||
</source> | </source> |
Version actuelle datée du 20 septembre 2024 à 16:58
Retour à la liste des Tds
Au besoin, la documentation QT peut-être intéressante : http://doc.qt.io/qt-5/signalsandslots.html
Sommaire
spécialisation de la classe QObject
Principe :
- créer nouvelle classe
- nom de la classe : MaClasse (respecter la casse : ! les capitales au bon endroit ! )
- Base class : QObject
- terminé !
// fichier dans lequel est déclaré la classe QObject
#include <QObject>
// on hérite de la classe QObject
class MaClasse : public QObject
{
// mot clé pour que qmake fasse son job pour les signaux/slots notamment
Q_OBJECT
public:
// constructeur de la classe :
// le "explicit" empêche de faire des conversions bizarroïdes entre classes
// ce n'est pas à retenir
explicit MaClasse(QObject *parent = nullptr);
signals:
public slots:
};
une classe utile :
On va faire une classe Lampe :
- elle aura un attribut privé : isAllume de type bool
- des slots (en gros le nom des méthodes sur QT) dont les prototypes sont :
- void allumer()
- void eteindre()
- void changerEtat()
- un signal
- il suffit de rajouter le signal dans la déclaration de la classe (header file), rien dans le cpp !
- on ajoute dans la partie signals:
- void valueChanged(int newValue);
- lorsque c'est nécessaire on envoie la nouvelle valeur de la façon suivante :
- emit valueChanged(valeur);
- il faut bien entendu remplacer valeur par un truc intéressant !
Remarque : vous pouvez laisser de côté changerEtat pour le moment.
Utilisation de la classe
ajouter un attribut dans la classe MainWindow
Pour ajouter un objet de notre nouvelle classe, on doit bien entendu ajouter sa définition à l'endroit où on souhaite l'utiliser :
#include "maclasse.h"
On va ensuite ajouter dans la classe MainWindow un attribut (ou plusieurs), de préférence privé :
....
class MainWindow : public ....
{
....
private :
MaClasse obj1;
MaClasse obj2;
...
}
relier signal avec slot
Il faut maintenant utiliser cet objet.
principe
Pour utiliser ce nouvel objet, on doit connecter des signaux et des slots.
Nous avons précédemment fait cette connexion graphiquement dans qtDesigner, ici nous allons utiliser la fonction connect.
connect(&objetEmetteur,&ClasseObjetEmetteur::signalEmis,&objetRecepteur,&ClasseObjetRecepteur::slotToExecute);
Les connections seront mises en place dans le constructeur de la classe MainWindow, à la fin du constructeur et après la mise en place de l'interface graphique :
MainWindow::MainWindow(QWidget *parent) :
QMainWindow(parent), ui(new Ui::MainWindow)
{
// mise en place de l'interface graphique
ui->setupUi(this);
// on ajoute ici les connexions
// objet vers mainwindow
connect(&obj,&ClasseObjetEmetteur::signalEmis,this,&MainWindow::monSlot);
// mainwindow vers objet
connect(this,&MainWindow::monSignal,&obj,&ClasseObjetRecepteur::slotToExecute);
// ou d'un objet graphique vers un objet de la nouvelle classe
connect(ui->pushButton,&ClasseObjetRecepteur::signalEmis,&obj,&ClasseObjetRecepteur::nomDuSlot);
}
afficher un message
Si ce n'est pas encore fait, ajouter dans un premier temps un affichage avec qDebug() dans vos méthodes allumer et éteindre.
Placer 2 boutons sur l'écran, et connecter ensuite les boutons sur les 2 méthodes allumer() et eteindre()
Si ça fonctionne, on peut supprimer les qDebug() dans la classe Lampe. Ajouter ensuite un nouveau SLOT dans la classe MainWindow, qui sera connecté sur le signal valueChanged(valeur) de la classe lampe.
Ce SLOT affichera sur la console,à l'aide d'un qDebug(), l'état de la lampe.
changer couleur d'un bouton
On souhaite maintenant utiliser 1 bouton pour visualiser l'état de la lampe : le bouton sera rouge ou noir suivant si la lampe est allumée ou non.
On écrira donc un nouveau SLOT (on conserve le SLOT qui permet d'afficher dans la console tel quel) qui changera la couleur du bouton.
Ce SLOT sera également connecté sur le signal valueChanged(valeur) : On peut connecter plusieurs SLOTs sur le même SIGNAL
Mettre en place cette visualisation
Remarque : pour différencier les boutons permettant de visualiser l'état des lampes des boutons à cliquer, on peut arrondir les angles des boutons, par ex :
ui->pushButton->setStyleSheet(QString::fromUtf8("background-color: red;"
"border-style: solid;"
"border-color: black;"
"border-width: 2px;"
"border-radius: 50px;")
);
// !! attention la valeur de "border-radius" doit être plus petite que la moitié de la longueur du plus petit côté du bouton
Plusieurs lampes
Ajouter plusieurs boutons, lampes, bouton pour changer l'état ...
clignotement avec QTimer
On peut facilement faire clignoter une lampe avec un QTimer :
- on choisit une durée : monTimer.setInterval(dure_Ms);
- le signal timeout est émis toutes les duree_Ms
- il faut se connecter sur le signal :
connect(&monTimer,&QTimer::timeout,
&maLampe,&Lampe::toggle);
- on lance le timer : monTimer.start();
Il faut bien entendu ajouter monTimer comme un attribut de la classe MainWindow (ajouter #include <QTimer>)