PDA

View Full Version : filter signal to limited slots



sriky27
26th March 2009, 13:23
Hi,

Is it possible to filter a common signal such that only few of the many clients who have connected to the signal receive them.

For example:

class customSignalling : public QObject
{
Q_OBJECT

public:
customSignalling(QObject* aParent);
register();

signals:
void sendSignal();

}


Here lets say classes A, B and C have connected to the signal
like

connect(customSignalling, SIGNAL(sendSignal()), this, SLOT(slot())),

Now can I limit the signal from being to C but A and B could receive it.
any permutation of it can I control the class objects which will receive.
Or is it a pure Broadcast.
:confused:
Please advise.

Regards,
Srikanth

^NyAw^
26th March 2009, 13:31
Hi,

Disconnect them

sriky27
26th March 2009, 13:52
I am sorry I didnot understand your solution.
Are you asking to use QObject::disconnect api.

Actually i am looking for a temporary disable and re-enabling the
connection is there any such possibility.

regards,
Srikanth

spirit
26th March 2009, 13:53
I am sorry I didnot understand your solution.
Are you asking to use QObject::disconnect api.

Actually i am looking for a temporary disable and re-enabling the
connection is there any such possibility.

regards,
Srikanth

take a look at QObject::blockSignals.

^NyAw^
26th March 2009, 14:00
Hi,

Do you know if there is performace difference using "blockSignals" or disconnecting them?



I am sorry I didnot understand your solution.
Are you asking to use QObject::disconnect api.


Yes, I think on disconnecting and reconnecting them when needed.
Also you can use "blockSignals" as spirit told you.

sriky27
26th March 2009, 14:21
Hi everyone,

Thanks for your suggestions, I have indeed gone through blocksignals,
i want to blocksignals to specific receivers, how to do that.

Regards,
Srikanth

Lykurg
26th March 2009, 14:23
Hi, blockSignals is no alternative to dis-/reconnect (in this case)

SENDER = emits the signal
A, B, C are receivers.

When setting SENDER.blockSignals(true) none of A,B,C will receive the signal. But as I have sriky27 understood, only e.g. B should not receive. So an special dis-/reconnect for B is necessary. Or you implement an member to A,B,C like "processSignal". (If A,B,C has an abstract base class I would prefer that instead of every time dis- and reconnect. If you need it often.)


void XXX::mySlot() {
if(!processSignal)
return;
//...
}

spirit
26th March 2009, 14:24
try this


...
const bool isBlocked = receiver->blockSignals(true);
//some actions
receiver->blockSignals(isBlocked);
...

Lykurg
26th March 2009, 14:28
receiver->blockSignals(true);
only avoid receiver to send signals, not to receive signals and execute slots

spirit
26th March 2009, 14:31
yep, my mistake, receiver must be replaced by sender.
but it will block ALL signals as was posted above.

sriky27
26th March 2009, 14:31
Hi everyone,

What I am trying to ask is: whether it is possible to send signals to few receivers only and block the rest. Is there any blockSignals(receievers, bool); api. How to do that??

Regards,
Sriky

spirit
26th March 2009, 14:33
hm, why you can't connect needed object with proper slots and don't connect another set of objects? :confused:

Lykurg
26th March 2009, 14:35
Is there any blockSignals(receievers, bool); api.
No.


How to do that?
Dis-/reconnect the classes by yourself (on runtime), or add a switch - as above mentioned - to your classes, which decides if the slot should be executed or not.

sriky27
26th March 2009, 14:49
Hi everyone,

I am writing an interface, where there is a common signal exposed sth like

class xxxx
{
register()

signals:
void doSomething();
};

Now there are many registered objects for the signal but only few of the objects should be notified.

Which is normally it is possible with asking the registered classes to implement an interface using which I could call the interface function of the specified objects I want.
That is the solution.
sth like

class interface
{
virtual void doSomething()=0;
]

class A: public interface
{
void doSomething();
}

class B: public interface
{
void doSomething();
}


class C: public interface
{
void doSomething();
}

when condition arises
Now having maintained the list of the objects
in QList<registeredClass> list;

for(;;)
{
if()
{
list.doSomething();
}
}


But as I don't want to use the above ,as Qt provides me with signal and slot mechanism,I want to use them and restrict the signal to only few of the many slots.

Regards,
Srikanth

Lykurg
26th March 2009, 14:55
class interface
{
virtual void doSomething()=0;
void setExecSlot(bool exec) {execSlot = exec;}
private:
bool m_execSlot;
}

class B: public interface
{
void doSomething() {if (!m_execSlot){return;} /*other stuff...*/}
}

//...
ptrToB->setExecSlot(false);
//...
ptrToB->setExecSlot(true);


There you have your "blockSignals(receievers, bool); api."

or

send a signal with an parameter which indicates which classes should "respect" the signal.

sriky27
26th March 2009, 15:20
Hi,

Thanks for your replies. The point I want to make it QObject has the list of all receivers, I just don't know how to get the receivers list or set the receiver list. Now I have to do the same book keeping that QObject does. I somehow not very much happy with the approach.

Regards,
Srikanth

sriky27
26th March 2009, 15:27
No.


Dis-/reconnect the classes by yourself (on runtime), or add a switch - as above mentioned - to your classes, which decides if the slot should be executed or not.


Hi,

How do you reconnect? In the class which emits the signals I donot know the slot of the receiver. If I have to do that I have to know upfront the type of the receivers which implement the slots would be? Please correct me if I am wrong.

Regards,
Srikanth

Lykurg
26th March 2009, 17:59
Well, at any point of your application you establish the connection via QObject::connect. In that class you - normally - have to do your reconnect.