Проблема здесь в том, что есть два сигнала с таким именем: 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), ...)
Я лично считаю это не очень полезным. Я ожидаю, что эта проблема исчезнет сама собой, когда Creator (или ваша IDE) автоматически вставит правильное приведение при автозавершении операции взятия PMF. А пока ...
Примечание: синтаксис подключения на основе 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){ /* ... */ });