supereater14
supereater14

Reputation: 147

Qt: How should I route a signal to the appropriate object dynamically?

I am writing an application in Qt. I am trying to create a system of signals and slots to connect a single controller thread to multiple threads which represent real-life devices. The number of devices is known at compile-time, but I would like it to be as easy as possible to change the number of them. My initial approach used templates on the signals, something like this:

signals:
    template<int whichOne> void updateDoohickeyState(dooHickeyState newState);

My hope was that I could then connect these to the devices like so:

connect(doohickeyController, doohickeyController::updateDoohickeyState<0>,
        doohickeys[0], doohickeyObject::updateState,
        Qt::QueuedConnection);

connect(doohickeyController, doohickeyController::updateDoohickeyState<1>,
        doohickeys[1], doohickeyObject::updateState,
        Qt::QueuedConnection);
// Etc...

Then, when I wanted to signal a device, I could do something like:

emit updateDoohickeyState<0>(doohickeyState);
emit updateDoohickeyState<1>(anotherDoohickeyState);

Unfortunately, Qt's MOC does not support templates on signals and slots; therefore, this does not work.

So, how else can I implement this? I have one controller which needs to signal to particular one of multiple identical devices in other threads. I would ideally like to do so without adding more signals (more complicated to update later), filtering slot-side (inefficient) or adding another class in the middle.

Upvotes: 0

Views: 174

Answers (2)

jwernerny
jwernerny

Reputation: 7048

It sounds like you might want a pub/sub service. It's quite easy to implement it in Qt using signals/slots and and a Q_Object for the service.

Upvotes: 0

Alexander Zavertan
Alexander Zavertan

Reputation: 342

You can invoke an object's slot directly using QMetaObject::invokeMethod instead of connected signal emission. Like this:

QMetaObject::invokeMethod(doohickeys[0], "updateState", Qt::QueuedConnection, Q_ARG(dooHickeyState, doohickeyState));
QMetaObject::invokeMethod(doohickeys[1], "updateState", Qt::QueuedConnection, Q_ARG(dooHickeyState, anotherDoohickeyState));

Upvotes: 3

Related Questions