How to pass Qt::ConnectionType to QObject::connect when connecting a lambda?
Asked Answered
S

2

13

I am connecting lambdas to QObject's signals:

    QObject::connect(handle, &BatchHandle::progressMax, [this](const ProcessHandle* const self, const int value) {
        this->maxProgress(value);
    });

The code above compiles with no problems.

However it's absolutely necessary that the Qt::QueuedConnection because the handle object will eventually move to another thread.

I added this to my code:

    QObject::connect(handle, &BatchHandle::finished, [this](const ProcessHandle* const self) {
        this->processIsRunning(false);
    }, (Qt::ConnectionType)Qt::QueuedConnection);

Notice how I added explicit cast to make sure it identifies the value type correctly. Result:

1>src\TechAdminServices\database\techCore\processes\import\ImportManagerDialog.cpp(191): error C2664: 'QMetaObject::Connection QObject::connect<void(__cdecl taservices::ProcessHandle::* )(const taservices::ProcessHandle *),Qt::ConnectionType>(const taservices::ProcessHandle *,Func1,const QObject *,Func2,Qt::ConnectionType)' : cannot convert parameter 3 from 'taservices::`anonymous-namespace'::<lambda58>' to 'const QObject *'
1>          with
1>          [
1>              Func1=void (__cdecl taservices::ProcessHandle::* )(const taservices::ProcessHandle *),
1>              Func2=Qt::ConnectionType
1>          ]
1>          No user-defined-conversion operator available that can perform this conversion, or the operator cannot be called

How to get a queued connection when connecting a lambda?

Spatterdash answered 10/2, 2017 at 14:42 Comment(1)
I thought for sure this would be a dupe, since the requirement for the target context does make it a bit unintuitive, but apparently not.Hypophosphite
A
23

I think you need to use the QObject::connect overload that allows you to specify the context in which the lambda should be invoked...

QObject::connect(
  handle,
  &BatchHandle::progressMax,
  target_context,   /* Target context parameter. */
  [this](const ProcessHandle* const self, const int value)
  {
    this->maxProgress(value);
  },
  Qt::QueuedConnection);
Alimentation answered 10/2, 2017 at 14:51 Comment(0)
G
-1

The queued connection can't work without the target object context, since it's this context that selects the queue the slot call gets inserted into. To be more obtusely, a QMetaCallEvent wrapping the functor is posted to the context object thread()'s event queue.

Glamour answered 10/2, 2017 at 16:37 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.