这两个 qt 信号槽连接之间的功能区别是什么?
What is the functional difference between these two qt signal-slot connections?
我正在使用带有 Visual Studio 2015 的 Qt 5.9.2 和 QtDesigner 来编写 Windows GUI 应用程序。我尝试通过以下调用连接我的一项操作:
connect(ui.myAction, &QAction::triggered, memberPtrToObjX_, &ClassX::Run);
但是 ClassX::Run 并不总是在单击菜单栏中的 myAction 后触发。调查这个问题,我想,使用 lambda 语法的相同信号槽连接有效:
connect(ui.myAction, &QAction::triggered, [this](bool run) { memberPtrToObjX_->Run(run); });
我很确定,这两个调用在语法上都是正确的。除了两个调用 return 一个有效的 QMetaObject::Connection,如果我保存 return 值并使用 operator bool() 检查。
显然我可以坚持使用工作 lambda 版本,但我很困惑并且更愿意知道我 "solution" 背后的原因。这两个调用之间是否存在任何功能差异,可以解释不同的行为?
QObject::connect()
的两个调用(由 OP 公开)在 this->memberPtrToObjX_
在 connect()
.
调用之后修改的情况下表现不同
第一个
connect(ui.myAction, &QAction::triggered, memberPtrToObjX_, &ClassX::Run);
Creates a connection of the given type from the signal in the sender object to the method in the receiver object. Returns a handle to the connection that can be used to disconnect it later.
因此,this->memberPtrToObjX_
中的当前指针连接为信号接收器。如果在connect()
之后修改了this->memberPtrToObjX_
,这对信号连接没有任何影响。
第二个
connect(ui.myAction, &QAction::triggered, [this](bool run) { memberPtrToObjX_->Run(run); });
Creates a connection from signal in sender object to functor, and returns a handle to the connection.
因此,lambda(后面的函子)作为接收者连接。 lambda 在执行时解析 this->memberPtrToObjX_
中的指针,即触发信号时。
第二个区别(最初在G.M的评论中发现)是连接类型:
第一个版本使用默认值 Qt::AutoConnection
(因为它没有明确定义)。带有 lambda 的版本总是使用 Qt::DirectConnection
。
如果 this->memberPtrToObjX_
中的指针不在同一线程中 "live",就会出现差异。在这种情况下,Qt::AutoConnection
被解析为 Qt::QueuedConnection
而不是 Qt::DirectConnection
。
我假设 this->memberPtrToObjX_
中的指针会在同一个 QThread
中 "live"。如果不是,第二个版本(带有 lambda)变得非常有问题,因为它在不同的线程中调用对象 "living" 的成员函数(此时很难判断该线程在做什么)。这只是 似乎 效果更好,但很可能是 "time bomb".
我正在使用带有 Visual Studio 2015 的 Qt 5.9.2 和 QtDesigner 来编写 Windows GUI 应用程序。我尝试通过以下调用连接我的一项操作:
connect(ui.myAction, &QAction::triggered, memberPtrToObjX_, &ClassX::Run);
但是 ClassX::Run 并不总是在单击菜单栏中的 myAction 后触发。调查这个问题,我想,使用 lambda 语法的相同信号槽连接有效:
connect(ui.myAction, &QAction::triggered, [this](bool run) { memberPtrToObjX_->Run(run); });
我很确定,这两个调用在语法上都是正确的。除了两个调用 return 一个有效的 QMetaObject::Connection,如果我保存 return 值并使用 operator bool() 检查。
显然我可以坚持使用工作 lambda 版本,但我很困惑并且更愿意知道我 "solution" 背后的原因。这两个调用之间是否存在任何功能差异,可以解释不同的行为?
QObject::connect()
的两个调用(由 OP 公开)在 this->memberPtrToObjX_
在 connect()
.
第一个
connect(ui.myAction, &QAction::triggered, memberPtrToObjX_, &ClassX::Run);
Creates a connection of the given type from the signal in the sender object to the method in the receiver object. Returns a handle to the connection that can be used to disconnect it later.
因此,this->memberPtrToObjX_
中的当前指针连接为信号接收器。如果在connect()
之后修改了this->memberPtrToObjX_
,这对信号连接没有任何影响。
第二个
connect(ui.myAction, &QAction::triggered, [this](bool run) { memberPtrToObjX_->Run(run); });
Creates a connection from signal in sender object to functor, and returns a handle to the connection.
因此,lambda(后面的函子)作为接收者连接。 lambda 在执行时解析 this->memberPtrToObjX_
中的指针,即触发信号时。
第二个区别(最初在G.M的评论中发现)是连接类型:
第一个版本使用默认值 Qt::AutoConnection
(因为它没有明确定义)。带有 lambda 的版本总是使用 Qt::DirectConnection
。
如果 this->memberPtrToObjX_
中的指针不在同一线程中 "live",就会出现差异。在这种情况下,Qt::AutoConnection
被解析为 Qt::QueuedConnection
而不是 Qt::DirectConnection
。
我假设 this->memberPtrToObjX_
中的指针会在同一个 QThread
中 "live"。如果不是,第二个版本(带有 lambda)变得非常有问题,因为它在不同的线程中调用对象 "living" 的成员函数(此时很难判断该线程在做什么)。这只是 似乎 效果更好,但很可能是 "time bomb".