PDA

View Full Version : check if object has any receivers



mortoray
20th October 2010, 11:44
Is there any way to iterate over the list of receivers for a QObject? Or failing that, a way to check if there are any receivers for an object.

I know about the "receivers" function, but it requires a specific signal. This will be error prone if I just call it for each signal (the moment somebody adds a new signal and forgets this function, it will break).

mortoray
20th October 2010, 12:48
It appears that "receivers" actually doesn't work. It always returns 0. So I don't even have that option.

wysota
20th October 2010, 12:59
It appears that "receivers" actually doesn't work. It always returns 0. So I don't even have that option.

You are probably calling it wrong.


This will be error prone if I just call it for each signal (the moment somebody adds a new signal and forgets this function, it will break).
If you ask the meta object for the list of signals then it won't break. That's what you should do anyway.

mortoray
20th October 2010, 13:09
This is the code I use to check for receivers. It is inside a "hasReceivers" function on the object I wish to check. The qDebug() statement is never reached, even when there are receivers for the object (I know this since they are actively receiving signals from it).



QMetaObject const * mo = metaObject();
for( int i=0; i < mo->methodCount(); ++i )
{
QMetaMethod m = mo->method( i );
if( m.methodType() != QMetaMethod::Signal )
continue;

if( receivers( m.signature() ) > 0 )
{
qDebug( m.signature() );
return true;
}
}

wysota
20th October 2010, 13:19
The signature doesn't take the SIGNAL() macro into consideration, try this:

QMetaObject const * mo = metaObject();
for( int i=0; i < mo->methodCount(); ++i )
{
QMetaMethod m = mo->method( i );
if( m.methodType() != QMetaMethod::Signal )
continue;

if( receivers( QString("1%1").arg(m.signature()).toAscii().constData() ) > 0 )
{
qDebug( m.signature() );
return true;
}
}

mortoray
20th October 2010, 13:36
That seems to work. What's with the "1" const in the string? Is there some standard macro I could use instead that would produce the same string in this case?

Though I realize now that I can't accomplish what I want anyway. The check I'm doing is to close a window, if there are no receivers on a particular object it doesn't need to prompt the user, if there are, then it does prompt. This window also connects to the object, so I momentarily disconnected, but I also have a child window that connects. Thus it's starting to get too complicated. :(

wysota
20th October 2010, 14:04
Is there some standard macro I could use instead that would produce the same string in this case?
Yes, SIGNAL() :)


Though I realize now that I can't accomplish what I want anyway. The check I'm doing is to close a window, if there are no receivers on a particular object it doesn't need to prompt the user, if there are, then it does prompt. This window also connects to the object, so I momentarily disconnected, but I also have a child window that connects. Thus it's starting to get too complicated. :(
It's much easier to get it done using a "subscriber" pattern and leave signal/slot mechanism for something else.

mortoray
20th October 2010, 14:17
Yes, SIGNAL() :)

I was assuming that won't work with dynamically generated strings. Does it?



It's much easier to get it done using a "subscriber" pattern and leave signal/slot mechanism for something else.

The slot mechanism is my subscriber pattern. That is, other than through the signals of this object the entities aren't related. I'm hoping to avoid having to duplicate this information == inevitably some future program will remember to "connect" but forget to "subscribe".

faldzip
20th October 2010, 14:23
The slot mechanism is my subscriber pattern. That is, other than through the signals of this object the entities aren't related. I'm hoping to avoid having to duplicate this information == inevitably some future program will remember to "connect" but forget to "subscribe".
But, as I understand your previous posts, you're now facing problem of window which did "connect" but is not the one which can "subscribe". So building subscriber pattern on signals/slots in that case won't work - this would be my guess.

wysota
20th October 2010, 14:33
I was assuming that won't work with dynamically generated strings. Does it?
No, that's why I placed "1" manually (actually I did that because I was hoping for the "what's with the '1'" question, but you can probably do it this way:

if( receivers( QString("%1%2").arg(SIGNAL("")).arg(m.signature()).toAscii().constData() ) > 0 )


The slot mechanism is my subscriber pattern.
It's not because of at least two reasons:
1. you don't control what happens when someone subscribes (i.e. calls connect())
2. you are using signals/slots yourself for other things so you have no idea who is subscribed.

You can wrap the signal/slot pattern into a subscribe/unsubscribe call and you'll have everything you need.


inevitably some future program will remember to "connect" but forget to "subscribe".
So make all the programs to subscribe() and not to connect(), then you won't have this problem.