Qt signály a sloty
Jednoduché příklady
Widget QPushButton
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.

Stisknutí tlačítka generuje signál clicked(), který je spojen se slotem quit() objektu app, který danou aplikaci ukončí.
Widgety QHBoxLayout, QSpinBox a QSlider
Demo Qt aplikace "Enter Your Age"

používá mechanismus signálů a slotů pro synchronizaci nastavení hodnot widgetů QSpinBox a QSlider. Umístění grafických prvků v okně aplikace řídí widget QHBoxLayout.
// hlavickove soubory se jmenuji stejne jako prislusne tridy
#include <QApplication>
#include <QSpinBox>
#include <QSlider>
#include <QHBoxLayout>
int main(int argc, char *argv[])
{
QApplication app(argc, argv);
// hlavni okno aplikace (titulek: zadej svuj vek)
QWidget* window = new QWidget;
window->setWindowTitle("Enter Your Age");
// komponenty pro interaktivni nastaveni hodnoty
QSpinBox* spinbox = new QSpinBox;
QSlider* slider = new QSlider(Qt::Horizontal);
spinbox->setRange(0, 130);
slider ->setRange(0, 130);
// zmeny v hodnotach komponent jsou vzajemne synchronizovany
QObject::connect(spinbox, SIGNAL(valueChanged(int)), slider, SLOT(setValue(int)));
QObject::connect(slider, SIGNAL(valueChanged(int)), spinbox, SLOT(setValue(int)));
spinbox->setValue(35);
// horizontalni rozmisteni komponent v okne aplikace
QHBoxLayout* layout = new QHBoxLayout;
layout->addWidget(spinbox);
layout->addWidget(slider);
window->setLayout(layout);
window->show();
return app.exec();
}
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