我使用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版本,但我很困惑,并且更愿意了解我的解决方案背后的原因"。这两个调用之间是否有任何功能差异,这解释了不同的行为?
答案 0 :(得分:0)
QObject::connect()
的两次调用(由OP公开)在调用this->memberPtrToObjX_
之后修改connect()
的情况下表现不同。
第一个
connect(ui.myAction, &QAction::triggered, memberPtrToObjX_, &ClassX::Run);
将发件人对象中信号的给定类型的连接创建到 receiver 中的方法 >对象。返回可用于以后断开连接的连接句柄。
因此,this->memberPtrToObjX_
中的当前指针作为信号接收器连接。如果在this->memberPtrToObjX_
之后修改connect()
,则不会对信号连接产生任何影响。
第二个
connect(ui.myAction, &QAction::triggered, [this](bool run) { memberPtrToObjX_->Run(run); });
创建从发件人对象信号到仿函数的连接,并返回连接的句柄。
因此,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"在另一个线程中(此时很难分辨该线程正在做什么)。这只似乎更好地工作,但很可能是"定时炸弹"。