Note that there are some explanatory texts on larger screens.

plurals
  1. PO
    primarykey
    data
    text
    <p>The simple answer is: you can't. Or, rather, you don't want (or need!) to use <code>sender()</code>. Simply capture and use <code>action</code>.</p> <pre><code>// Important! // vvvv connect(action, &amp;QAction::triggered, this, [action, this]() { // use action as you wish ... }); </code></pre> <p>The specification of <code>this</code> as the object context for the functor ensures that the functor will not get invoked if either the action or <code>this</code> (a <code>QObject</code>) cease to exist. Otherwise, the functor would try to reference dangling pointers.</p> <p>In general, the following must hold when capturing context variables for a functor passed to <code>connect</code>, in order to avoid the use of dangling pointers/references:</p> <ol> <li><p>The pointers to the source and target objects of <code>connect</code> can be captured by value, as above. It is guaranteed that if the functor is invoked, both ends of the connection exist. </p> <pre><code>connect(a, &amp;A::foo, b, [a, b]{}); </code></pre> <p>Scenarios where <code>a</code> and <code>b</code> are in different threads require special attention. It can not be guaranteed that once the functor is entered, some thread will not delete either object.</p> <p>It is idiomatic that an object is only destructed in its <code>thread()</code>, or in any thread if <code>thread() == nullptr</code>. Since a thread's event loop invokes the functor, the null thread is never a problem for <code>b</code> - without a thread the functor won't be invoked. Alas, there's no guarantee about the lifetime of <code>a</code> in <code>b</code>'s thread. It is thus safer to capture the necessary state of the action by value instead, so that <code>a</code>'s lifetime is not a concern.</p> <pre><code>// SAFE auto aName = a-&gt;objectName(); connect(a, &amp;A::foo, b, [aName, b]{ qDebug() &lt;&lt; aName; }); // UNSAFE connect(a, &amp;A::foo, b, [a,b]{ qDebug() &lt;&lt; a-&gt;objectName(); }); </code></pre></li> <li><p>Raw pointers to other objects can be captured by value if you're absolutely sure that the lifetime of the objects they point to overlaps the lifetime of the connection.</p> <pre><code>static C c; auto p = &amp;c; connect(..., [p]{}); </code></pre></li> <li><p>Ditto for references to objects:</p> <pre><code>static D d; connect(..., [&amp;d]{}); </code></pre></li> <li><p>Non-copyable objects that don't derive from <code>QObject</code> should be captured through their shared pointers by value.</p> <pre><code>std::shared_ptr&lt;E&gt; e { new E }; QSharedPointer&lt;F&gt; f { new F; } connect(..., [e,f]{}); </code></pre></li> <li><p><code>QObject</code>s living in the same thread can be captured by a <code>QPointer</code>; its value must be checked prior to use in the functor.</p> <pre><code>QPointer&lt;QObject&gt; g { this-&gt;parent(); } connect(..., [g]{ if (g) ... }); </code></pre></li> <li><p><code>QObject</code>s living in other threads must be captured by a shared pointer or a weak pointer. Their parent must be unset prior to their destruction, otherwise you'll have double deletes:</p> <pre><code>class I : public QObject { ... ~I() { setParent(nullptr); } }; std::shared_ptr&lt;I&gt; i { new I }; connect(..., [i]{ ... }); std::weak_ptr&lt;I&gt; j { i }; connect(..., [j]{ auto jp = j.lock(); if (jp) { ... } }); </code></pre></li> </ol>
    singulars
    1. This table or related slice is empty.
    plurals
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. VO
      singulars
      1. This table or related slice is empty.
    2. VO
      singulars
      1. This table or related slice is empty.
    3. VO
      singulars
      1. This table or related slice is empty.
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload