문제는 여기에 있다는 것입니다 이 : 그 이름을 가진 신호가 QSpinBox::valueChanged(int)
와 QSpinBox::valueChanged(QString)
. Qt 5.7부터 원하는 과부하를 선택하기 위해 제공되는 도우미 기능이 있으므로 작성할 수 있습니다
connect(spinbox, qOverload<int>(&QSpinBox::valueChanged),
slider, &QSlider::setValue);
Qt 5.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), ...)
나는 개인적으로 그것이 실제로 유용하지 않다는 것을 알았습니다. 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 은
참고 :이 클래스에서는 Signal valueChanged가 오버로드됩니다. 함수 포인터 구문을 사용하여이 신호에 연결하기 위해 Qt는 다음 예제와 같이 함수 포인터를 얻는 편리한 도우미를 제공합니다.
connect(spinBox, QOverload<const QString &>::of(&QSpinBox::valueChanged),
[=](const QString &text){ /* ... */ });