Qt6 и новый синтаксис сигналов и слотов
Хочу разобраться в том, как использовать новый синтаксис сигналов и слотов в Qt5 на основе указателей на методы. Из книги я взял такой код:
#include <QApplication>
#include <QHBoxLayout>
#include <QSlider>
#include <QSpinBox>
int main(int argc, char *argv[])
{
QApplication app(argc, argv);
QWidget* window = new QWidget;
window->setWindowTitle("Set your age");
QSpinBox* spinBox = new QSpinBox;
QSlider* slider = new QSlider(Qt::Horizontal);
spinBox->setRange(0, 130);
slider->setRange(0, 130);
QObject::connect(spinBox, &QSpinBox::valueChanged, slider, &QSlider::setValue);
QObject::connect(slider, SIGNAL(valueChanged(int)), spinBox, SLOT(setValue(int)));
spinBox->setValue(35);
QHBoxLayout* layout = new QHBoxLayout;
layout->addWidget(spinBox);
layout->addWidget(slider);
window->setLayout(layout);
window->show();
return app.exec();
}
И немного поправил строку, чтобы вместо макросов использовались указатели на методы:
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))' 17 |
QObject::connect(spinBox, &QSpinBox::valueChanged, slider, &QSlider::setValue); | ~~~~~~~~~~~~~~~~^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Как правильно использовать сигналы и слоты с новым синтаксисом, чтобы такая ошибка не возникала?
Ответы (1 шт):
Проблема возникает потому, что в вызове connect нет однозначности какую перегрузку valueChanged использовать. А в классе QSpinBox их две:
void valueChanged(int);
void valueChanged(const QString &);
В справке об этом сигнале, кстати, как раз указано про способ разрешения этой проблемы:
Note: Signal valueChanged is overloaded in this class. To connect to this signal by using the function pointer syntax, Qt provides a convenient helper for obtaining the function pointer as shown in this example:
connect(spinBox, QOverload<int>::of(&QSpinBox::valueChanged), [=](int i){ /* ... */ });
Чуть лаконичнее это делается с помощью хелпер шаблона qOverload:
connect(spinBox, qOverload<int>(&QSpinBox::valueChanged),
[=](int i){ /* ... */ });
А вот в Qt6 (который упомянут в заголовке вопроса) подобной проблемы похоже бы не возникло, т.к. они убрали перегрузку со строкой и она теперь имеет самостоятельное название:
void QSpinBox::textChanged(const QString &text)