Qt Map Signals Based On Parameter Value - c++

I know that i can use QSignalMapper to call a slot with different parameters based on connection. What i want to achieve is a little different.
We are using plugins in our application and different plugins are responsible for different types of objects. We are connecting multiple slots, each implemented in a different plugin, to one signal emitted by the main application. One of the parameters of the signal is a QString indicating the type of object associated with the signal. Currently, we are checking this parameter in the slots and proceed if the type is handled by the plugin. This has a downside, every plugin does this checking and i want to avoid this if possible.
I want to connect all slots to the same signal, and when the signal is emitted, only the appropriate slot is called depending on the value of the QString argument, kind of like a QSignalMapper but in a different way.
Is there any built-in mechanism to do this? If not, any ideas on how i can achieve this?
Thank you in advance.

I don't think there's a component for that, but you could create your own signal mapper like this:
create a MySignalMapper component
code an addSourceSignal method to set the signal of the main app
code an addDestinationSlot method that takes a QString/slot pair and maps the string to the slot.
in your component connect the source signal to a custom slot that dispatches based on the qstring value. You can invoke a slot with QMetaObject::invokeMethod.

Qxt has a class exactly for this functionality. You can use QxtSlotMapper class which is in QxtCore module.
http://libqxt.bitbucket.org/doc/tip/qxtslotmapper.html

You could restrict the allowed values of the "type" string to be valid C++ function names only. Force the plugins to name their slots according to the types they handle, then for each plugin simply attempt to connect the appropriately named slots.
In other words, you could do what QMetaObject::connectSlotsByName, except implement your own naming convention.

Related

QT: Signal / Slot connection via connect or on_

I am new to QT. As far as I can see, there are two ways to connect signals and slots with each other. One way would be using the connect method. When e.g. wanting to put a method ButtonReleased() to the slot that is triggered after the released() signal of a pushButton with name pushButton, one could write:
connect(ui->pushButton, SIGNAL(released()), this, SLOT(ButtonPressed()));
However, as far as I see, one could also define a method with name on_pushButton_released() to achieve the same connection. Is there any difference between both methods and if so, which one is preferred?
Thanks in advance!
There are indeed two main ways to connect signals to slots.
The first one, using the connect method allows to connect any signal to any slot (or signal) as long as the function signatures match. This is the main way to connect signals in Qt.
The second way are member methods that are called on_ObjectName_SignalName(). These are automatically connected by Qt, if a UI element called ObjectName exists and has a signal called SignalName. This is specifically meant for the use case of having some Widget with a separate .ui file, which contains these elements that you want to connect to. As such, this mechanism does not work if you create UI elements "by hand" in your C++ code.
As you can see, the second mechanism has very specific requirements that need to be satisfied to work, although these are not uncommon. So if you have satisfied these conditions I see no Problem in doing it this way, but others may disagree and this is largely personal preference.
Also note: The syntax in your question is the old syntax from Qt4. If you are using Qt5 and newer, it is highly advised to use the new syntax.
You can read more about signals and slots on the Qt Documentation.

Qt connect of a ui member and two signals in the same connection

I would like to understand a simple piece of code I came across. It is a connection between an object of the interface and two signals.
The code is:
connect( ui->checkbox_legEnabled,
SIGNAL( stateChanged( int ) ), SIGNAL( edited() ) );
What is the meaning of this line of code?
Thanks,
Sara
With Qt signals and slots, you can directly connect one signal to another signal (or non-signal member function), without having a slot in between. See connection function invoked here is this overload of QObject::connect.
This line of code hence means, whenever the object ui->checkbox_legEnabled (presumably some kind of QCheckbox) emits the stateChanged signal (that has an int parameter passed along), directly emit another signal (or ordinary member function) edited (without parameters).
Short answer is you can connect a signal to another signal and that means that the second signal will also emit whenever the first signal is emitted, read more about signals and slots in the documentation here, also check out the new way to call connect (with function pointers)
Now in your case what it does it's basically allows you to keep the ui private, but in the same time forward the signals you want to the outside of your object, by allowing other objects to connect to the signal(s) you provide in the interface.
Incomplete usage example (based on your code, i named the class that contains your code MyWidget): the main-window (or whoever) that has access to your widget can be notified whenever something changes inside, by connecting to the edited signal:
void MainWindow::createMyWidget()
{
m_myWidget = new MyWidget(this);
connect(m_myWidget, &MyWidget::edited, this, &MainWindow::myWidgetWasEdited));
}
This way whenever something changes inside MyWidget the MainWindow can be notified about the edit and it can take the necessary actions inside the myWidgetWasEdited slot.
This can be expanded, if needed, to provide an signal for each particular "edit" instead of a single generic edited signal (but this depends on your needs).

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.
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));
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.

qt asynchronous completion for object member

I have a QObject class processing requests. So I could create a SLOT process(QString). I would like to know when the request was processed - i.e. receive a future of some kind that I can wait for. It should be possible to relate reults to corresponding requests.
But since the SLOT can't return a value, I'm a bit stuck... Can this be achieved with the Qt SIGNAL/SLOT mechanism?
Your slot can emit a signal when it is done (with any data you need as arguments) that you can then connect to, to do other stuff at that point.

Can QSignalMapper forward function arguments?

How could I use QSignalMapper to map multiple check box?
The signal from check box I would use is stateChanged(int flag). During the process I want to keep this int flag and it will be finally send to my custom slot with other mapped variables.
How could I achieve this? I am using Qt4.
You cannot directly forward function arguments with a QSignalMapper. There are two ways to work around this.
Rewrite a custom version of QSignalMapper that takes the appropriate function arguments and forwards them.
Connect the check box signal directly to the slot you want and check the return value of sender() in the slot to see which check box emitted the signal.