在使用Qt 5中的新信号和槽连接语法(使用成员函数指针)时,我遇到了一些问题。根据新的信号槽语法的描述,我尝试将以下代码:
cpp
QObject::connect(spinBox, SIGNAL(valueChanged(int)),
slider, SLOT(setValue(int)));
改为:
cpp
QObject::connect(spinBox, &QSpinBox::valueChanged,
slider, &QSlider::setValue);
但在编译时出现错误:
error: no matching function for call to QObject::connect(QSpinBox*&,
<unresolved overloaded function type>, QSlider*&, void
(QAbstractSlider::*)(int))
我在Linux上使用clang和gcc编译,且都使用了-std=c++11
选项。
问题分析
错误消息指出:"unresolved overloaded function type"
。编译器无法确定你是指QSpinBox::valueChanged(int)
还是QSpinBox::valueChanged(QString)
,因为这两个信号名称是重载的。
解决方法
使用qOverload (Qt 5.7及更高版本)
从Qt 5.7开始,提供了一些辅助函数来简化选择特定重载的方法,可以这样写:
cpp
connect(spinBox, qOverload<int>(&QSpinBox::valueChanged),
slider, &QSlider::setValue);
早期版本的解决方案
对于Qt 5.6及更早版本,你需要通过类型转换明确指定要使用的重载信号:
cpp
connect(spinBox, static_cast<void (QSpinBox::*)(int)>(&QSpinBox::valueChanged),
slider, &QSlider::setValue);
虽然这种方法看起来不美观,但这是解决问题的唯一办法。因此,最好避免信号和槽的重载。
使用宏定义简化代码
你可以定义一个宏来简化类型转换:
cpp
#define CONNECTCAST(OBJECT, TYPE, FUNC) static_cast<void(OBJECT::*)(TYPE)>(&OBJECT::FUNC)
之后,使用这个宏来连接信号和槽:
cpp
QObject::connect(spinBox, CONNECTCAST(QSpinBox, int, valueChanged),
slider, &QSlider::setValue);
使用lambda表达式
另一种方法是使用lambda表达式将槽包装起来:
cpp
connect(spinBox, static_cast<void (QSpinBox::*)(int)>(&QSpinBox::valueChanged),
[slider](int value) { slider->setValue(value); });
这样可以避免显式的类型转换,使代码更简洁。
总结
在Qt 5中,当处理重载信号和槽时,有多种方法可以选择正确的重载。根据你的Qt版本,可以使用辅助函数qOverload
、类型转换、宏定义或者lambda表达式来解决这个问题。无论哪种方法,都能确保在编译时进行类型检查,从而提高代码的可靠性。