Jeff G
Jeff G

Reputation: 4677

Qt Connect Event to non-QObject Types

I have a data model object, with a method intended to handle Qt events. 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. Since my data model doesn't inherit from QObject, this code generates error C2664:

Types pointed to are unrelated; conversion requires reinterpret_cast, C-style cast or function-style cast

Is there a way to connect event handlers to non-QObject types? 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?

Upvotes: 0

Views: 754

Answers (2)

cbuchart
cbuchart

Reputation: 11555

One of the new connection options available since Qt 5 is the use of lambda as slots, very useful in these situations:

// 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>(...).

Upvotes: 1

Jeff G
Jeff G

Reputation: 4677

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(&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.

Upvotes: 0

Related Questions