Qt 连接事件到非 QObject 类型
Posted
技术标签:
【中文标题】Qt 连接事件到非 QObject 类型【英文标题】:Qt Connect Event to non-QObject Types 【发布时间】:2019-09-15 04:55:58 【问题描述】:我有一个数据模型对象,它带有一个用于处理 Qt 事件的方法。但是,当我尝试将事件处理程序连接到此方法时,会出现编译时错误。问题是connect
模板最终会在第四个参数上执行static_cast<void (QObject::*)(double)>
。由于我的数据模型不是从 QObject
继承的,因此此代码会生成错误 C2664:
指向的类型是不相关的;转换需要 reinterpret_cast、C-style cast 或 function-style cast
有没有办法将事件处理程序连接到非 QObject 类型?一个最小的例子:
struct DataModel
void handle(double)
;
DataModel data;
QDoubleSpinBox spinBox;
connect(&spinBox, QOverload<double>::of(&QDoubleSpinBox::valueChanged),
&data, &DataModel::handle);
鉴于所有“连接”方法所做的只是设置事件转发,因此这种类型要求似乎没有必要。我们不能在那里使用任何有效的函数指针是有原因的吗?
【问题讨论】:
【参考方案1】:自 Qt 5 以来可用的新连接选项之一是使用 lambda 作为 slots,在这些情况下非常有用:
// adapt the capture to your specific situation
connect(&spinBox, qOverload<double>(&QDoubleSpinBox::valueChanged),
[&data](double arg) data.handle(arg); );
PS:我使用了一个较短的形式来选择正确的重载,您可能会发现它很有用:qOverload<double>(...)
。
【讨论】:
这在功能上与我想出的答案相同,但由于使用 lambda 而不是std::bind
更简洁。我无法让较短的 qOverload
表单在 Windows 上工作。【参考方案2】:
还有一个连接模板重载可以接受任何类型的函数对象。因此,我能够将我的connect
方法调用重写为:
connect(&spinBox, QOverload<double>::of(&QDoubleSpinBox::valueChanged),
std::bind(std::mem_fn(&DataModel::handle), &data, std::placeholders::_1);
然后 Qt 不会尝试将任何内容转换为不兼容的类型。
【讨论】:
以上是关于Qt 连接事件到非 QObject 类型的主要内容,如果未能解决你的问题,请参考以下文章