PDA

View Full Version : Signals and Slots



ggdev001
20th February 2013, 07:55
Hello,

in my app I have a custom class for networking that uses a QNetworkAccessManager object inside it.
From the QNetworkAccessManager's requestFinished(..) slot I emit some custom signal that carries some data
and which I want to handle in other classes.

My problem is following. Imagine in some class B, I tie a slot to the signal I mentioned above.
Then I tie another slot to this signal. In the end we may have that to my signal (customSignal) there are
10 slots connected in some other class B. I don't want that once the signal is emitted all these
10 slots get called simultaneously. Rather at some point in time, I want the signal to call
only one slot, at another point in time, only another slot and etc.

How can I achieve this?

I know I could for example use different my custom network objects (but I was told it is not recommended??).
e.g., like this:


MyNetworkClass *network1 = new MyNetworkClass();
bool res = QObject::connect(network1, SIGNAL(signalSuccess(QVariant)), this, SLOT(CustomSLot1(QVariant)));

MyNetworkClass *network2 = new MyNetworkClass();
bool res = QObject::connect(network2, SIGNAL(signalSuccess(QVariant)), this, SLOT(CustomSLot2(QVariant)));

MyNetworkClass *network3 = new MyNetworkClass();
bool res = QObject::connect(network3, SIGNAL(signalSuccess(QVariant)), this, SLOT(CustomSLot3(QVariant)));




I think it would work this way also??? Thanks.

Santosh Reddy
20th February 2013, 08:24
Instead have one network object with different signals

signalSuccess1(QVariant)
signalSuccess2(QVariant)
signalSuccess3(QVariant)
..

lanz
20th February 2013, 08:45
If you're trying to balance load between threads, I suggest you used producer-consumer pattern(wiki (http://en.wikipedia.org/wiki/Producer-consumer_problem)).

Or you can implement custom recipient object, that will call only one slot, somewhat along the lines:

class CustomRecipient {
public slots:
void CallOneSlot (QVariant var) {
// or any other marshalling scheme
current_callee = (++current_callee) % callee.size ();
QMetaObject::invokeMethod (callee[current_calle], slot_name[current_callee], Q_ARG(QVariant, var));
};
private:
QVector<QObject*> callee;
QVector<QString> slot_name;
int current_callee;
};

ggdev001
20th February 2013, 08:53
Let's put the question a bit differently.
If I connect many slots to one signal. What will happen each time signal gets emitted??


Instead have one network object with different signals

signalSuccess1(QVariant)
signalSuccess2(QVariant)
signalSuccess3(QVariant)
..
I will think about your suggestion, but then I may need to pass somehow some parameter to the
MyNetworkClass object which will tell it which signal to emit in the requestFinished??? (I am not sure if
it will cause some problem if some network calls are made in parallel etc.).

lanz
20th February 2013, 09:22
Let's put the question a bit differently.
If I connect many slots to one signal. What will happen each time signal gets emitted??


Every connected slot will be emitted once in no particular order.

Edit:
Since Qt 4.6, as Lesiok correctly points out, slots are called in the same order as they were connected.

Lykurg
20th February 2013, 09:30
in no particular order.That is true, but I remember that I saw some time ago, I think it was in the source code(?), that the connect statements will be executed in order they have been established. The reason what was given for that was, that if this would change, most applications would break because nobody cares about the information you gave :D So it is kind of a self made standard...

Lesiok
20th February 2013, 13:07
Every connected slot will be emitted once in no particular order.
FALSE ! From Qt doc (http://qt-project.org/doc/qt-4.8/signalsandslots.html#signals-and-slots) :
If several slots are connected to one signal, the slots will be executed one after the other, in the order they have been connected, when the signal is emitted.