[Qt-interest] Runtime Error :- connect: No such slot ...

Bradley T. Hughes bradley.hughes at nokia.com
Fri Feb 19 15:56:32 CET 2010


On 02/19/2010 03:23 PM, Andre Somers wrote:
> Bradley T. Hughes wrote:
>> On 02/19/2010 01:10 PM, Sean Harmer wrote:
>>> On Friday 19 February 2010 12:03:29 Bradley T. Hughes wrote:
>>>> On 02/19/2010 12:38 PM, Sean Harmer wrote:
>>>>> Normally connect is smart enough to figure this out, but in your
>>>>> case the QThread object has affinity with the GUI thread even
>>>>> though you emit the signal in the context of the worker thread.
>>>>> So you need to be explicit here.
>>>>
>>>> Actually, emit is smart enough to handle this as well. If you emit
>>>> a signal for an object that is not affine to the current thread,
>>>> the connection will be queued (when using the default
>>>> Qt::AutoConnection, of course).
 >>>
>>> Ah OK that's good to know. I had thought that the queued/direct
>>> decision was made at the time of the connect statement. Is this
>>> deferred decision making in the case of Qt::AutoConnection something
>>> new or has this always been the case?
>>
>> It's always been the case (since the thread affinity of sender/receiver
>> can change at any time). The decision is always made at emit time;
>> connect() just stores the connection type.
>
> It could, but does it happen often enough to warrant the overhead?

There's actually not that much overhead (apart from fetching the current 
thread's id which would not be necessary otherwise). Explicitly setting the 
connection type already requires code that looks like this (grossly 
simplified, of course):

foreach (Connection c, connectionsToSignal) {
     if (c->connectionType == QueuedConnection) {
         postMetaCall(c->receiver, c->member);
         continue;
     }
     // must be DirectConnection
     c->receiver->callout(args);
}

After adding support for run-time evaluated auto:

foreach (Connection *c, sender->d->connectionsToSignal) {
     if ((c->connectionType == AutoConnection
           && (c->receiver->thread() != sender->thread()
                || currentThread != sender->thread()))
         || c->connectionType == QueuedConnection) {
         postMetaCall(c->receiver, c->member);
         continue;
     }
     // must be DirectConnection
     c->receiver->callout(args);
}

For the real thing:

http://qt.gitorious.org/qt/qt/blobs/4.6/src/corelib/kernel/qobject.cpp#line3239

> Then again, you could set a direct connection explicitly if you need the
> speed increase, if that's measurable at all...

The difference between a QueuedConnection and a DirectConnection is 
measurable, since the former goes through QApplication::postEvent(). The 
latter is just a virtual function call into the moc generated method 
dispatch code (for those interested, it's the qt_metacall() member that moc 
generates for your classes).

-- 
Bradley T. Hughes (Nokia-D-Qt/Oslo), bradley.hughes at nokia.com
Sandakervn. 116, P.O. Box 4332 Nydalen, 0402 Oslo, Norway



More information about the Qt-interest-old mailing list