如何在连接lambda时将Qt :: ConnectionType传递给QObject :: connect?

时间:2017-02-10 14:42:18

标签: c++ qt lambda signals-slots qobject

我将lambdas连接到QObject的信号:

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

上面的代码编译没有任何问题。

然而,Qt::QueuedConnection绝对必要,因为handle对象最终将移动到另一个线程。

我将此添加到我的代码中:

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

注意我是如何添加显式强制转换以确保它正确识别值类型的。结果:

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

连接lambda时如何获得排队连接?

2 个答案:

答案 0 :(得分:10)

我认为您需要使用允许您指定应调用lambda的上下文的QObject::connect overload ...

QObject::connect(
  handle,
  &BatchHandle::progressMax,
  target_context,   /* Target context parameter. */
  [this](const ProcessHandle* const self, const int value)
  {
    this->maxProgress(value);
  },
  Qt::QueuedConnection);

答案 1 :(得分:0)

排队连接无法在没有目标对象上下文的情况下工作,因为它是选择插槽调用插入的队列的上下文。 To be more obtusely,将QMetaCallEvent包裹着的仿函数发布到上下文对象thread()的事件队列中。