Tomáš Zato
Tomáš Zato

Reputation: 53193

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

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?

Upvotes: 14

Views: 6964

Answers (2)

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.

Upvotes: -1

G.M.
G.M.

Reputation: 12899

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);

Upvotes: 25

Related Questions