简体   繁体   English

Qt Connect事件到非QObject类型

[英]Qt Connect Event to non-QObject Types

I have a data model object, with a method intended to handle Qt events. 我有一个数据模型对象,其对象旨在处理Qt事件。 However, when I attempt to connect an event handlers to this method, I get a compile-time error. 但是,当我尝试将事件处理程序连接到此方法时,出现编译时错误。 The issue is that the connect template eventually performs a static_cast<void (QObject::*)(double)> on the fourth argument. 问题在于, connect模板最终会对第四个参数执行static_cast<void (QObject::*)(double)> Since my data model doesn't inherit from QObject , this code generates error C2664: 由于我的数据模型不继承自QObject ,因此此代码生成错误C2664:

Types pointed to are unrelated; 指向的类型无关。 conversion requires reinterpret_cast, C-style cast or function-style cast 转换需要reinterpret_cast,C样式强制转换或函数样式强制转换

Is there a way to connect event handlers to non-QObject types? 有没有一种方法可以将事件处理程序连接到非QObject类型? A minimal example: 一个最小的例子:

struct DataModel {
    void handle(double) { }
};

DataModel data;
QDoubleSpinBox spinBox;
connect(&spinBox, QOverload<double>::of(&QDoubleSpinBox::valueChanged),
    &data, &DataModel::handle);

This type requirement seems unnecessary given that all the "connect" method does is setup event forwarding. 鉴于所有“连接”方法所做的只是设置事件转发,因此这种类型的要求似乎是不必要的。 Is there a reason why we can't use any valid function pointer there? 为什么不能在那里使用任何有效的函数指针?

One of the new connection options available since Qt 5 is the use of lambda as slots , very useful in these situations: 从Qt 5开始可用的新连接选项之一是使用lambda作为插槽 ,在以下情况下非常有用:

// adapt the capture to your specific situation
connect(&spinBox, qOverload<double>(&QDoubleSpinBox::valueChanged),
       [&data](double arg) { data.handle(arg); });

PS: I've used a shorter form to choose the correct overload, that you may find useful: qOverload<double>(...) . PS:我使用了一种较短的形式来选择正确的重载,您可能会发现它有用: qOverload<double>(...)

There is another connect template overload that takes any kind of function object. 还有另一个连接模板重载,它可以接受任何类型的功能对象。 Therefore, I was able to rewrite my connect method call as: 因此,我能够将我的connect方法调用重写为:

connect(&spinBox, QOverload<double>::of(&QDoubleSpinBox::valueChanged),
    std::bind(std::mem_fn(&DataModel::handle), &data, std::placeholders::_1);

Then Qt doesn't attempt to cast anything to an incompatible type. 然后,Qt不会尝试将任何内容强制转换为不兼容的类型。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM