Problem polega na tym, że istnieją dwa sygnały o tej nazwie: QSpinBox::valueChanged(int)
i QSpinBox::valueChanged(QString)
. Od Qt 5.7 dostępne są funkcje pomocnicze do wybierania żądanego przeciążenia, dzięki czemu można pisać
connect(spinbox, qOverload<int>(&QSpinBox::valueChanged),
slider, &QSlider::setValue);
W przypadku Qt 5.6 i wcześniejszych musisz powiedzieć Qt, który chcesz wybrać, rzucając go na odpowiedni typ:
connect(spinbox, static_cast<void (QSpinBox::*)(int)>(&QSpinBox::valueChanged),
slider, &QSlider::setValue);
Wiem, to brzydkie . Ale nie da się tego obejść. Dzisiejsza lekcja brzmi: nie przeciążaj swoich sygnałów i slotów!
Dodatek : to, co naprawdę denerwuje w obsadzie, to to
- jeden powtarza nazwę klasy dwukrotnie
- należy określić wartość zwracaną, nawet jeśli jest to zwykle
void
(dla sygnałów).
Więc czasami używam tego fragmentu kodu 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;
}
};
Stosowanie:
connect(spinbox, SELECT<int>::OVERLOAD_OF(&QSpinBox::valueChanged), ...)
Osobiście uważam, że nie jest to przydatne. Spodziewam się, że ten problem sam zniknie, gdy Kreator (lub twoje IDE) automatycznie wstawi odpowiednią obsadę podczas automatycznego uzupełniania operacji pobierania PMF. Ale w międzyczasie ...
Uwaga: składnia połączenia oparta na PMF nie wymaga C ++ 11 !
Dodatek 2 : w Qt 5.7 zostały dodane funkcje pomocnicze w celu złagodzenia tego problemu, wzorowane na moim obejściu powyżej. Głównym pomocnikiem jest qOverload
(masz też qConstOverload
i qNonConstOverload
).
Przykład użycia (z dokumentacji):
struct Foo {
void overloadedFunction();
void overloadedFunction(int, QString);
};
qOverload<>(&Foo:overloadedFunction)
qOverload<int, QString>(&Foo:overloadedFunction)
QOverload<>::of(&Foo:overloadedFunction)
QOverload<int, QString>::of(&Foo:overloadedFunction)
Dodatek 3 : jeśli spojrzysz na dokumentację dowolnego przeciążonego sygnału, teraz rozwiązanie problemu przeciążenia jest jasno określone w samych dokumentach. Na przykład https://doc.qt.io/qt-5/qspinbox.html#valueChanged-1 mówi
Uwaga: Signal valueChanged jest przeciążony w tej klasie. Aby połączyć się z tym sygnałem przy użyciu składni wskaźnika funkcji, Qt zapewnia wygodny pomocnik do uzyskiwania wskaźnika funkcji, jak pokazano w tym przykładzie:
connect(spinBox, QOverload<const QString &>::of(&QSpinBox::valueChanged),
[=](const QString &text){ });