这两个qt信号槽连接之间的功能差异是什么?

时间:2018-02-22 16:43:06

标签: qt lambda connect signals-slots

我使用Qt 5.9.2与Visual Studio 2015和QtDesigner一起编写Windows GUI应用程序。我尝试通过以下调用连接我的一个动作:

connect(ui.myAction, &QAction::triggered, memberPtrToObjX_, &ClassX::Run);

但是,在菜单栏中单击myAction后,并不总是会触发ClassX :: Run。我想,调查这个问题,使用lambda语法的相同信号槽连接起作用:

connect(ui.myAction, &QAction::triggered, [this](bool run) { memberPtrToObjX_->Run(run); });

我很确定,这两个调用在语法上都是正确的。除了两个调用都返回一个有效的QMetaObject::Connection,如果我保存返回值并检查操作符bool()。

显然我可以坚持工作的lambda版本,但我很困惑,并且更愿意了解我的解决方案背后的原因"。这两个调用之间是否有任何功能差异,这解释了不同的行为?

1 个答案:

答案 0 :(得分:0)

QObject::connect()的两次调用(由OP公开)在调用this->memberPtrToObjX_之后修改connect()的情况下表现不同。

第一个

connect(ui.myAction, &QAction::triggered, memberPtrToObjX_, &ClassX::Run);

调用
QMetaObject::Connection QObject::connect(
const QObject *sender, PointerToMemberFunction signal,
const QObject *receiver, PointerToMemberFunction method,
Qt::ConnectionType type = Qt::AutoConnection)

  

发件人对象中信号的给定类型的连接创建到 receiver 中的方法 >对象。返回可用于以后断开连接的连接句柄。

因此,this->memberPtrToObjX_中的当前指针作为信号接收器连接。如果在this->memberPtrToObjX_之后修改connect(),则不会对信号连接产生任何影响。

第二个

connect(ui.myAction, &QAction::triggered, [this](bool run) { memberPtrToObjX_->Run(run); });

调用
QMetaObject::Connection QObject::connect(
const QObject *sender, PointerToMemberFunction signal,
Functor functor)

  

创建从发件人对象信号仿函数的连接,并返回连接的句柄。

因此,lambda后面的(仿函数)作为接收器连接。 lambda在执行时解析指针this->memberPtrToObjX_,即触发信号时。

第二个区别(最初在G.M.的评论中发现)是连接类型:

第一个版本使用默认值Qt::AutoConnection(因为它未明确定义)。带lambda的版本总是使用Qt::DirectConnection

如果this->memberPtrToObjX_中的指针对象在同一个帖子中没有"live",则会出现差异。在这种情况下,Qt::AutoConnection已解析为Qt::QueuedConnection而不是Qt::DirectConnection

我认为this->memberPtrToObjX_中的指针将会#34;生活"在同一个QThread。如果没有,第二个版本(带有lambda)变得非常值得怀疑,因为它调用了对象的成员函数" living"在另一个线程中(此时很难分辨该线程正在做什么)。这只似乎更好地工作,但很可能是"定时炸弹"。