I want to send some custom events between two Qt objects, but without making a relation between them. Normally in Qt we can send custom events (QApplication::sendEvent) but we must specify a pointer to receiver object! But when that two objects are in different scope (i.e. some widget, and receiver is some object managing database) sharing a pointer to receiver could be problematic.
I created an event dispatcher object for handling custom evens. Its operation is very simple - at the one side, Qt object can send custom event to dispatcher (dispatcher is a receiver), and second object (receiver) subscribes to receive that custom events. Both objects doesn't know about each other, but dispatcher must be globally available from any place in code (which is not a huge problem). Example simplified code:
EventDispatcher.h
class EventDispatcher : public QObject
{
public:
EventDispatcher() = default;
bool event(QEvent* e) override;
void registerObj(QObject* obj)
{
subscribers.push_back(obj);
}
private:
std::vector<QObject*> subscribers;
};
EventDispatcher.cpp
bool EventDispatcher::event(QEvent *e)
{
if(e->type() == QCustomEvent::type())
{
//getValue is a specific method of QCustomEvent
qDebug() << "custom event received. Value: " << ((QCustomEvent*)e)->getValue();
for(auto* s : subscribers)
QApplication::sendEvent(s, e);
return true;
}
return QObject::event(e);
}
Usage - sending events:
//QCustomEvent inherits from the QEvent
QCoreApplication::sendEvent(g_eventDispatcherInstance, new QCustomEvent());
Usage - registering:
g_evd->registerObj(ui->widget_4);
//we can receive and handle that custom event in widget_4 class in bool event(QEvent* ev) override; method
However i have a belief that it can be done simpler, without making a intermediate dispatcher class, using only Qt classes, and without coupling both of them - sander and receiver. Hmm, but looking at this question: Post events without specifying target object in Qt , looks like it is not so trivial, and making some kind of dispatcher is unavoidable :-|