Re: [Interest] Using connect/disconnect with lambdas

2018-02-19 Thread Thiago Macieira
On Sunday, 18 February 2018 20:59:50 PST Tom Isaacson via Interest wrote:
> I'm replacing some old SIGNAL/SLOT connects with the new Qt5 format and I
> need to use lambdas for some of them.
> 
> Scenario 1:
> 
> public slots:
> void RouteEditName();
> void RouteEditName(QString name);
> 
> m_pRouteEditNameAct = new tAction(tr("Name route") + "...", this);
> connect(m_pRouteEditNameAct, SIGNAL(triggered()), this,
> SLOT(RouteEditName()), Qt::QueuedConnection);
> 
> If someone has been naughty and overloaded a slot then normally I'd just use
> a lambda to indicate which slot is being called:
> connect(m_pRouteEditNameAct, this, &tAction::triggered, [this]() {
> RouteEditName(); });

Make this a four-argument connect.

> But in this case I need to add Qt::QueuedConnection but connect() won't take
> four params like this: connect(m_pRouteEditNameAct, this,
> &tAction::triggered, [this]() { RouteEditName(); }, Qt::QueuedConnection);

Make this one a five-argument connect().

> Do I just add an unnecessary 'this' to fill it out?
> connect(m_pRouteEditNameAct, this, &tAction::triggered, this, [this]() {
> RouteEditName(); }, Qt::QueuedConnection);

It's not unnecessary. It's good practice.

And in your case, absolutely necessary. You cannot queue a connection without 
a target QObject to be queued to. THAT is what that extra "this" is for.

> Scenario 2:
> 
> Later I need to disconnect this:
> disconnect(m_pRouteEditNameAct, SIGNAL(triggered()), this,
> SLOT(RouteEditName()));
> 
> But how do I disconnect a lambda?
> disconnect(m_pRouteEditNameAct, &tAction::triggered, this, [this]() {
> RouteEditName(); });

disconnect() does not have such an overload. To disconnect anew-style connect, 
you must pass the QMetaObject::Connection object that connect() returned.

-- 
Thiago Macieira - thiago.macieira (AT) intel.com
  Software Architect - Intel Open Source Technology Center



___
Interest mailing list
Interest@qt-project.org
http://lists.qt-project.org/mailman/listinfo/interest


Re: [Interest] Using connect/disconnect with lambdas

2018-02-19 Thread Benjamin TERRIER
2018-02-19 5:59 GMT+01:00 Tom Isaacson via Interest :
> I'm replacing some old SIGNAL/SLOT connects with the new Qt5 format and I 
> need to use lambdas for some of them.
>
> Scenario 1:
>
> public slots:
> void RouteEditName();
> void RouteEditName(QString name);
>
> m_pRouteEditNameAct = new tAction(tr("Name route") + "...", this);
> connect(m_pRouteEditNameAct, SIGNAL(triggered()), this, 
> SLOT(RouteEditName()), Qt::QueuedConnection);
>
> If someone has been naughty and overloaded a slot then normally I'd just use 
> a lambda to indicate which slot is being called:
> connect(m_pRouteEditNameAct, this, &tAction::triggered, [this]() { 
> RouteEditName(); });
>
> But in this case I need to add Qt::QueuedConnection but connect() won't take 
> four params like this:
> connect(m_pRouteEditNameAct, this, &tAction::triggered, [this]() { 
> RouteEditName(); }, Qt::QueuedConnection);
>
> Do I just add an unnecessary 'this' to fill it out?
> connect(m_pRouteEditNameAct, this, &tAction::triggered, this, [this]() { 
> RouteEditName(); }, Qt::QueuedConnection);
>

There is a big difference between :
connect(ptr, SIGNAL(triggered()), ptr2, SLOT(mySlot()));
and
connect(ptr, &Ptr::triggered, ptr2, [ptr2]() { ptr2->mySlot(); });
and
connect(ptr, &Ptr::triggered, [ptr2]() { ptr2->mySlot(); });

The first 2 forms behave identically and the slot (and lambda) is
executed in the thread
of the ptr2 object.
While the 3rd form executes the lambda and the slot in the thread of ptr object.

So if you want to solve overloads by using lambdas you should use the 2nd form.
Alternatively, you can use QOverload and qOverload to resolve the
overload without having to pay for a lambda.

Br,

Benjamin
___
Interest mailing list
Interest@qt-project.org
http://lists.qt-project.org/mailman/listinfo/interest


Re: [Interest] Using connect/disconnect with lambdas

2018-02-19 Thread Pierre-Yves Siret
2018-02-19 5:59 GMT+01:00 Tom Isaacson via Interest :

> I'm replacing some old SIGNAL/SLOT connects with the new Qt5 format and I
> need to use lambdas for some of them.
>
> Scenario 1:
>
> public slots:
> void RouteEditName();
> void RouteEditName(QString name);
>
> m_pRouteEditNameAct = new tAction(tr("Name route") + "...", this);
> connect(m_pRouteEditNameAct, SIGNAL(triggered()), this,
> SLOT(RouteEditName()), Qt::QueuedConnection);
>
> If someone has been naughty and overloaded a slot then normally I'd just
> use a lambda to indicate which slot is being called:
> connect(m_pRouteEditNameAct, this, &tAction::triggered, [this]() {
> RouteEditName(); });
>

You can use connect(m_pRouteEditNameAct, &tAction::triggered,
this, QOverload<>::of(&YourClass::RouteEditName))

and QOverload::of(&YourClass::RouteEditName) for the other
overload.

More info here: http://doc.qt.io/qt-5/qtglobal.html#qOverload (note that
the c++14 syntax is shorter than the one I described).
___
Interest mailing list
Interest@qt-project.org
http://lists.qt-project.org/mailman/listinfo/interest


Re: [Interest] Using connect/disconnect with lambdas

2018-02-18 Thread Nikos Chantziaras

On 19/02/18 06:59, Tom Isaacson via Interest wrote:

But how do I disconnect a lambda?
 disconnect(m_pRouteEditNameAct, &tAction::triggered, this, [this]() { 
RouteEditName(); });

This seems like it's trying to disconnect from a different lambda to the one I 
originally connected to.


Store the connection:

  class Blah {
  QMetaObject::Connection connection;
  };

  connection = connect(/* ... */);

You can then disconnect it with:

  disconnect(connection);

___
Interest mailing list
Interest@qt-project.org
http://lists.qt-project.org/mailman/listinfo/interest