[Interest] Signal/Slot connection fails, even though QMetaObject::activate is called

Matthew Woehlke mwoehlke.floss at gmail.com
Mon Feb 17 22:27:45 CET 2020


On 15/02/2020 00.40, Max Paperno wrote:
> On 2/14/2020 11:19 PM, Tony Rietwyk wrote (in part):
>> Both overloads have the following warning:
> 
> No they don't... Looking at doc.qt.io for 5.14 anyway. Only the one with
> `context` has the part about the context being destroyed (emphasis mine):
> 
> "The connection will automatically disconnect if the sender **or the
> context** is destroyed."
> 
> To me this says that you specifically want the connection to be
> destroyed when the `context` object goes away, in case the sender and
> receiver/context objects aren't the same for some reason.

The sender and receiver/context are *rarely* the same... that would be a
self-signalling object.

You probably meant that they *share lifetime*, and you'd be right that
that is often the case... until it isn't. Just because it's true *today*
doesn't mean it will be true *tomorrow* as your project changes. Some UI
element you expected to be around "forever" or to have exactly one
instance might suddenly become dynamic.

It's *always* safer to be explicit about the receiving context.

> If the lambda code only affects stuff in the sender object (or stuff
> unrelated to any object), then it probably doesn't matter.

Right; in this case, you can *maybe* get away with it... but see also
the follow-up about the *thread* context. Even here, you're probably
safer reusing the sender as the receiving context.

> Seems clear that for objects in different threads the sender and
> receiver/context wouldn't be the same, hence the connection type
> parameter in that overload.

Sure, but the connection type has other uses. Sometimes, for instance,
you want to force a queued connection to defer handling of an event.
(Especially true for cases where you might handle several of the same
event in one event loop "cycle". Techniques like merging update requests
are usually implemented with explicitly queued events.)

I don't think I've *ever* used DirectConnection, but I've definitely
used QueuedConnection. (Most of the time, of course AutoConnection is
correct.)

>> In my experience, coding in particular ways "because it scares you"
>> often leads to poor results.

WG21 disagrees. Many C++ programmers think that naked `new`/`delete` are
scary, and the general direction is to *encourage* this. Being "scared"
of a programming practice that is *well known* to be easily and
frequently misused is not a bad thing.

If you'd said something like "my code *never* checks for array bounds
overflow", I would have the same reaction. (Note: "because my indexing
operators will throw" doesn't count; that *is* checking.)

>> A C++ lambda is basically a temporary object with the copied or
>> referenced state
Right. And if the owner of those references goes out of scope before the
lambda...

(Keep in mind that copied pointers are, effectively, *also references*.
You're probably okay for non-capturing lambdas or lambdas that genuinely
only capture values, but in my experience, those are rare, at least as
slots. The vast majority of my lambdas capture either `this` or `d`.)

-- 
Matthew


More information about the Interest mailing list