我很难理解Qt 5中新的信号/插槽语法(使用指向成员函数的指针),如新信号时隙语法中所述。我试着改变这个:
QObject::connect(spinBox, SIGNAL(valueChanged(int)),
slider, SLOT(setValue(int));对此:
QObject::connect(spinBox, &QSpinBox::valueChanged,
slider, &QSlider::setValue);但是,当我试图编译它时,我会得到一个错误:
错误:没有调用
QObject::connect(QSpinBox*&, <unresolved overloaded function type>, QSlider*&, void (QAbstractSlider::*)(int))的匹配函数
我试过在Linux上使用clang和gcc,都是用-std=c++11。
我做错了什么,我该怎么补救?
发布于 2013-05-28 15:18:14
这里的问题是,有两个名称为的信号:QSpinBox::valueChanged(int)和QSpinBox::valueChanged(QString)。在QT5.7中,提供了一些帮助函数来选择所需的重载,因此您可以编写
connect(spinbox, qOverload<int>(&QSpinBox::valueChanged),
slider, &QSlider::setValue);对于Qt5.6和更早版本,您需要通过将Qt转换为正确的类型来告诉Qt您要选择哪一个:
connect(spinbox, static_cast<void (QSpinBox::*)(int)>(&QSpinBox::valueChanged),
slider, &QSlider::setValue);我知道,这是丑陋的。但这是无法避免的。今天的教训是:不要超载你的信号和插槽!
增编:演员们真正烦人的是
void (对于信号)。因此,我发现自己有时会使用以下C++11片段:
template<typename... Args> struct SELECT {
template<typename C, typename R>
static constexpr auto OVERLOAD_OF( R (C::*pmf)(Args...) ) -> decltype(pmf) {
return pmf;
}
};用法:
connect(spinbox, SELECT<int>::OVERLOAD_OF(&QSpinBox::valueChanged), ...)我个人认为这并不是很有用。我希望当Creator (或您的IDE)在自动完成获取PMF的操作时自动插入正确的强制转换时,这个问题就会自行解决。但与此同时..。
注意:基于PMF的连接语法不需要C++11!
增编2:在QT5.7中添加了帮助函数来缓解这种情况,这是根据我前面的解决方法建立的。主要的助手是qOverload (您还拥有qConstOverload和qNonConstOverload)。
用法示例(来自文档):
struct Foo {
void overloadedFunction();
void overloadedFunction(int, QString);
};
// requires C++14
qOverload<>(&Foo:overloadedFunction)
qOverload<int, QString>(&Foo:overloadedFunction)
// same, with C++11
QOverload<>::of(&Foo:overloadedFunction)
QOverload<int, QString>::of(&Foo:overloadedFunction)增编3:如果您查看任何重载信号的文档,现在解决重载问题的方法已经在文档本身中清楚地说明了。例如,https://doc.qt.io/qt-5/qspinbox.html#valueChanged-1说
注意:信号valueChanged在这个类中重载。为了通过使用函数指针语法连接到此信号,Qt提供了一个方便的助手,用于获取函数指针,如本例所示: 连接(spinBox,QOverload::of(&QSpinBox::valueChanged),={ /* . */ });
发布于 2016-05-18 14:42:44
错误信息是:
错误:没有调用
QObject::connect(QSpinBox*&, <unresolved overloaded function type>, QSlider*&, void (QAbstractSlider::*)(int))的匹配函数
其中的重要部分是提到“未解决的重载函数类型”。编译器不知道您指的是QSpinBox::valueChanged(int)还是QSpinBox::valueChanged(QString)。
有几种解决重载的方法:
connect()提供合适的模板参数
QObject::connect(spinBox,&QSpinBox::valueChanged,slider &QSlider::setValue);
这迫使connect()将&QSpinBox::valueChanged解析为接受int的重载。
如果时隙参数有未解决的重载,则需要向connect()提供第二个模板参数。不幸的是,没有语法可以要求第一个被推断,所以您需要同时提供这两个语法。这时,第二种方法可以提供帮助:signal将选择所需的重载,现在可以成功地将其替换到模板中。这与“时隙”的论点同样有效,而且我发现在这种情况下,它不那么麻烦。static_cast,因为它只是一种强制,而不是删除语言的保护。我用的是:
//还有助于使?:运算符同意的第二次和//第三次论点。template T&& coerce(U& u) {返回u;}
这让我们可以写
连接(spinBox,spinBox滑块,&QSlider::setValue);发布于 2014-06-07 11:08:45
实际上,您可以用lambda包装您的插槽,如下所示:
connect(spinbox, static_cast<void (QSpinBox::*)(int)>(&QSpinBox::valueChanged),
slider, &QSlider::setValue);会更好看的。*\
https://stackoverflow.com/questions/16794695
复制相似问题