Qt signály a sloty

Z GeoWikiCZ

Jednoduché příklady

Tlačítko

Do kostry Qt aplikace doplníme tři řádky, které postupně vytvoří objekt typu QPushButton (tlačítko), spojí signál clicked() objektu button se slotem quit() objektu app a zobrazí widget button

#include <QApplication>
#include <QPushButton>

int main(int argc, char *argv[])
{
    QApplication app(argc, argv);

    QPushButton* button = new QPushButton("Quit");
    QObject::connect(button, SIGNAL(clicked()), &app, SLOT(quit()));
    button->show();
    
    return app.exec();
}

Výsledná minimalistická aplikace obsahuje jediné tlačítko, jehož stisknutí generuje signál clicked(), který je spojen se slotem quit(),který danou aplikaci ukončí.


Třída Counter

Třída Counter (čítač) je definována jako veřejný potomek třídy QObject

#ifndef COUNTER_H
#define COUNTER_H

#include <QObject>

class Counter : public QObject
 {
     Q_OBJECT

 public:
     Counter() { m_value = 0; }

     int value() const { return m_value; }

 public slots:
     void setValue(int value);

 signals:
     void valueChanged(int newValue);

 private:
     int m_value;
 };

#endif // COUNTER_H

Makro Q_OBJECT musí být použito pro každou třídu, která má definovat vlastní Qt signály a sloty. Zdrojový text je zpracován nejprve preprocesorem, výsledkem je standardní C++ kód, který je následně zpracován C++ překladačem.

Návěští public slots: (rozšíření syntaxe C++) uvozuje defininici slotů, které definujeme stejně jako standardní C++ členské funkce (metody). Podobně návěští signals: uvozuje definici signálů, které jsou ale narozdíl od slotů definovány preprocesorem.

Jediné v čem se definice slotů liší od standardních C++ metod je v tom, že příkazem emit emitují signály.

#include "counter.h"

 void Counter::setValue(int value)
 {
     if (value != m_value) {
         m_value = value;
         emit valueChanged(value);
     }
 }

Objek, který emituje signál neví nic o objektech, které jsou registrovány pro přijetí daného signálů. Povšimněte si, že metoda setValue(int) obsahuje podmínku, která zabraňuje emitování signálů v případě, že se stav daného objektu nemění.

Spojení signálů a slotů zajišťuje metoda QObject::connect, kteráv následujícím příkladu spojuje signál emitovaný objektem a a slotem objektu b.

#include <iostream>
#include "counter.h"

int main()
{
    using std::cout;

    Counter a, b;
    QObject::connect(&a, SIGNAL(valueChanged(int)),
                     &b, SLOT  (setValue(int))   );

    cout << "a, b intial values : " << a.value() << "  " << b.value() << "\n";
    b.setValue(333);
    cout << "a, b        values : " << a.value() << "  " << b.value() << "\n";
    a.setValue(12);
    cout << "a, b final  values : " << a.value() << "  " << b.value() << "\n";
}

Uvedený příklad demonstruje, že signály a sloty můžeme používat nejen v grafických widgetech Qt. Výstup dané konzolové aplikace je

a, b intial values : 0  0
a, b        values : 0  333
a, b final  values : 12  12