【问题标题】:Qt Connect Event to non-QObject TypesQt 连接事件到非 QObject 类型
【发布时间】: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);

鉴于所有“连接”方法所做的只是设置事件转发,因此这种类型要求似乎没有必要。我们不能在那里使用任何有效的函数指针是有原因的吗?

【问题讨论】:

    标签: c++ qt events event-handling qt5


    【解决方案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&lt;double&gt;(...)

    【讨论】:

    • 这在功能上与我想出的答案相同,但由于使用 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 不会尝试将任何内容转换为不兼容的类型。

    【讨论】:

      猜你喜欢
      • 2014-01-10
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多