Wszystkie klasy biblioteki Qt dziedziczą po klasie bazowej QObject. Klasa ta zapewnia obsługę elementów biblioteki Qt jakimi są sloty i sygnały, które umożliwiają realizację obsługi interakcji pomiędzy obiektami dziedziczącymi po klasie QObject.
Sloty można porównać do gniazdka, natomiast sygnały do wtyczki. Pod dany slot (wtyczkę) można podpiąć sygnał (gniazdko). Ważne jest jednak, aby slot i sygnał do siebie pasowały tak jak dana wtyczka musi pasować do gniazdka.
W powyższym kodzie sender jest wskaźnikiem na obiekt wysyłający sygnał. Obiekt ten ma zaimplementowany wewnątrz slot o nazwie onEvent. Z kolei reciver jest wskaźnikiem na obiekt otrzymujący sygnał. Ten obiekt ma zaimplementowany wewnątrz sygnał o nazwie reciveEvent. Aby dany sygnał pasował do danego slotu argumenty, jakie one otrzymują muszą być takie same.
Możliwa jest również operacja odwrotna do połączenia slotu z sygnałem:
QObject::disconnect(sender, reciver);
Czas najwyższy by utworzyć przykład klasy, która będzie miała zaimplementowany slot i sygnały. W tym celu należy kliknąć prawym przyciskiem myszy (tak jak to jest widoczne na poniższym rysunku) i w menu kontekstowym kliknąć pozycję Dodaj nowy.
Po tym jakże trudnym zadaniu oczom twym ukazać powinno się okno dialogowe Nowy plik, w którym to niezwłocznie po zaznaczeniu opcji z poniższego screen-a należy kliknąć przycisk Wybierz (co też i ja uczyniłem z najdzikszą rozkoszą).
W kolejnym oknie należy podać nazwę tworzonej klasy, ja wybrałem niezbyt wyszukaną nazwę: A po czym kliknąłem przycisk Dalej.
Niestety Qt Creator okazuje się być niezwykle gadatliwym tworem, gada i gada i gęba mu się nie zamyka i z tego powodu w ostatnim widoku okna Klasa C++ pyta się, pod który projekt utworzoną klasę podpiąć. W tym przypadku wypada zostawić tak jak jest i kliknąć przycisk Zakończ.
Uff, po tym jakże nużącym procesie klikania i skakania po oknach Qt Creator-a do projektu powinny zostać dodane dwa pliki:
A.h;
A.cpp;
W pliku A.h kod klasy A należy zmodyfikować do następującej postaci:
#ifndef A_H
#define A_H
#include <QObject>
#include <QDebug>
class A : public QObject{ // klasa A musi dziedziczyć po klasie QObject
Q_OBJECT // w pierwszej linijce klasy musi być uruchomione makro Q_OBJECT
QString name;
public:
A(QString name): name(name){}
public slots: // sekcja dla slotów publicznych (mogą być też prywatne i chronione sloty)
void sendMessage(QString to, QString message); // slot do wysyłania wiadomości
void messageRecived(QString from, QString to, QString message); // slot do otrzymywania wiadomości
signals: // sekcja dla sygnałów
void messageSended(QString from, QString to, QString string); // sygnał wywoływany (emitowany), gdy wysłana zostanie wiadomość
};
#endif // A_H
Natomiast plik A.cpp należy zmodyfikować do następującej postaci:
#include "a.h"
void A::sendMessage(QString to, QString message){
emit messageSended(name, to, message); // tutaj uruchamiany jest slot podpięty pod sygnał wysłanej wiadomości
}
void A::messageRecived(QString from, QString to, QString message){
if(to == name){ // jeżeli nazwa odbiorcy wiadomości jest równa nazwie nadanej obiektowi klasy to
qDebug() << name << "recived some message from:" << from << "and this message is:" << message; // wyświetlaj taką informację
}
}
W pliku main.cpp kod powinien wyglądać mniej więcej tak:
#include <QCoreApplication>
#include "a.h"
int main(int argc, char *argv[])
{
QCoreApplication a(argc, argv);
A *a1 = new A("a1"); // tworzę obiekt klasy A
A *a2 = new A("a2");
// łączenie sygnałów i slotów
QObject::connect(a1, SIGNAL(messageSended(QString,QString,QString)), a2, SLOT(messageRecived(QString,QString,QString)));
QObject::connect(a2, SIGNAL(messageSended(QString,QString,QString)), a1, SLOT(messageRecived(QString,QString,QString)));
a1->sendMessage("a2", "Hey, what are you doing here?"); // slot sendMessage obiektu a1, który emituje sygnał messageSended
a2->sendMessage("a1", "I spend some time on programming dude!"); // slot sendMessage obiektu a2, który emituje sygnał messageSended
return a.exec();
}
Wynik działania powyższego kodu:
"a2" recived some message from: "a1" and this message is: "Hey, what are you doing here?"
"a1" recived some message from: "a2" and this message is: "I spend some time on programming dude!"