tags: - TODO - QT - C++
Signal / Slot Mechanism
- The Signal/Slot mechanism is proper to Qt.
- It hides an automatic implementation of callbacks registration.
Adding signal/slot handling
Your class must inherit from QObject (through QWidget for example) to be able to use the signal/slot mechanism.
Also, the macro Q_OBJECT must be present in your class under its public: attributes :
#include <QWidget>
#include <string>
class MyEmitterClass : public QWidget
{
public:
// Macro
Q_OBJECT
// Constructor
explicit MyEmitterClass() {}
// Dummy function to use signal
void sayHi() {emit sigSay("Hi");}
// Used signals
signals:
void sigSay(std::string str);
}
// ------------------------------------------
#include <QWidget>
#include <string>
#include <iostream>
class MyReceiverClass : public QWidget
{
public:
// Macro
Q_OBJECT
// Constructor
explicit MyReceiverClass(MyEmitterClass& em)
{
// Link our slot to the object signal
if(!QObject::connect(&em,&MyEmitterClass::sigSay,
this,&MyReceiverClass::sayingSomething))
{
std::cout << "Connect error" << std::endl;
}
}
// Possible slots
private slots:
void sayingSomething(std::string str)
{
std::cout << str << std::endl;
}
}
// -----------------------------------------------
// Main
MyEmitterClass emitter;
MyReceiverClass receiv(emitter);
emitter.sayHi();
Signals
- Signals can be seen as a
doActionOnRegisteredCallbacks(args). - They must be written under
signals:tag. - To distribute this signal, the syntax is such as
emit mySignal(args). - The
emitwill call all the registered callbacks and exit only when those are done.
Slots
- Slots are the functions called when the corresponding signal is emitted.
- Those are always listed under
private slots:tag. - The function signature must match the signal signature.
- They can be called like normal functions.
Linking both
Linking the signals and slots require to know which object must be linked to which, and which function is linked to which signal :
QObject::connect(const QObject ptrSender, const char *ptrSignal, const QObject ptrSignal, const char *ptrSlot);
The function return true if the connection happened successfully.
It is also possible to disconnect both by the same way :
QObject::disconnect(const QObject ptrSender, const char *ptrSignal, const QObject ptrSignal, const char *ptrSlot);
Note
- Use this notation to connect signals and slots.
- An older one exists, but does not ensure compatibilities and your program may crash on run.
Stop signals temporarily
If, for any case, you need to stop the emitting of signals (you are modifying objects with temporarily NULL pointers that should not be used while not replaced, and a signal would be emitted in that case) :
// some code with signal/slot working
{
const QSignalBlocker blocker(&myObjectToBlockSignalsFrom); // block events
// some code without signal/slot for this object
}
// some code with signal/slot working
The creation of the signal blocker will automatically inhibit emitting of any signals for targeted object.
When destroyed, it will automatically re-enable the signals.