Le problème ici est qu'il y a deux signaux avec ce nom: QSpinBox::valueChanged(int)
et QSpinBox::valueChanged(QString)
. À partir de Qt 5.7, des fonctions d'assistance sont fournies pour sélectionner la surcharge souhaitée, vous pouvez donc écrire
connect(spinbox, qOverload<int>(&QSpinBox::valueChanged),
slider, &QSlider::setValue);
Pour Qt 5.6 et les versions antérieures, vous devez indiquer à Qt celui que vous voulez choisir, en le castant dans le bon type:
connect(spinbox, static_cast<void (QSpinBox::*)(int)>(&QSpinBox::valueChanged),
slider, &QSlider::setValue);
Je sais, c'est moche . Mais il n'y a aucun moyen de contourner cela. La leçon d'aujourd'hui est la suivante: ne surchargez pas vos signaux et vos slots!
Addendum : ce qui est vraiment ennuyeux avec le casting, c'est que
- on répète le nom de la classe deux fois
- il faut spécifier la valeur de retour même si c'est habituellement
void
(pour les signaux).
Je me suis donc retrouvé à utiliser parfois cet extrait de code 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;
}
};
Usage:
connect(spinbox, SELECT<int>::OVERLOAD_OF(&QSpinBox::valueChanged), ...)
Personnellement, je le trouve pas vraiment utile. Je m'attends à ce que ce problème disparaisse de lui-même lorsque Creator (ou votre IDE) insérera automatiquement la bonne distribution lors de la finalisation automatique de l'opération de prise du PMF. Mais en attendant ...
Remarque: la syntaxe de connexion basée sur PMF ne nécessite pas C ++ 11 !
Addendum 2 : dans Qt 5.7, des fonctions d'assistance ont été ajoutées pour atténuer ce problème, sur le modèle de ma solution de contournement ci-dessus. L'assistant principal est qOverload
(vous avez aussi qConstOverload
et qNonConstOverload
).
Exemple d'utilisation (à partir de la documentation):
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)
Addendum 3 : si vous regardez la documentation de tout signal surchargé, la solution au problème de surcharge est maintenant clairement indiquée dans la documentation elle-même. Par exemple, https://doc.qt.io/qt-5/qspinbox.html#valueChanged-1 dit
Remarque: le signal valueChanged est surchargé dans cette classe. Pour se connecter à ce signal en utilisant la syntaxe du pointeur de fonction, Qt fournit une aide pratique pour obtenir le pointeur de fonction comme indiqué dans cet exemple:
connect(spinBox, QOverload<const QString &>::of(&QSpinBox::valueChanged),
[=](const QString &text){ /* ... */ });