这里的问题是,有两个名称相同的信号:QSpinBox::valueChanged(int)
和QSpinBox::valueChanged(QString)
。从Qt 5.7开始,提供了一些辅助函数来选择所需的重载,因此您可以编写
connect(spinbox, qOverload<int>(&QSpinBox::valueChanged),
slider, &QSlider::setValue);
对于Qt 5.6和更早的版本,您需要通过将其强制转换为正确的类型来告诉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), ...)
我个人认为它不是真正有用。我希望当自动完成拍摄PMF的操作时,Creator(或您的IDE)会自动插入正确的类型转换时,此问题会自行解决。但是与此同时...
注意:基于PMF的连接语法不需要C ++ 11!
附录2:在Qt 5.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提供了一个方便的助手来获取功能指针,如本示例所示:
connect(spinBox, QOverload<const QString &>::of(&QSpinBox::valueChanged),
[=](const QString &text){ /* ... */ });