Signal/Slot unresolved overloaded function type QSpinBox
-
Hi there,
Today I stumbled upon an error that comes from connecting a QSpinBox valueChanged Signal to a
void member function:the connect statement:
connect(spinBoxUtc, &QSpinBox::valueChanged, this, &MainWindow::fillData);
and this is the private function fillData():
void MainWindow::fillData() { SendDataToPol dataToPol; dataToPol.timeSelection = comboBoxTime->currentText(); dataToPol.timezone = spinBoxUtc->value(); dataToPol.longitude = doubleSpinBoxLong->value(); dataToPol.polarisRa = timeEditPolarisRa->time(); emit sendData(dataToPol); }
On compiling I get this error:
../pat_tab/mainwindow.cpp: In constructor 'MainWindow::MainWindow(QWidget*)': ../pat_tab/mainwindow.cpp:99:74: error: no matching function for call to 'MainWindow::connect(QSpinBox*&, <unresolved overloaded function type>, MainWindow*, void (MainWindow::*)())' connect(spinBoxUtc, &QSpinBox::valueChanged, this, &MainWindow::fillData); ^ ../pat_tab/mainwindow.cpp:99:74: note: candidates are: In file included from /usr/include/qt5/QtWidgets/qwidget.h:38:0, from /usr/include/qt5/QtWidgets/QWidget:1, from ../pat_tab/mainwindow.h:4, from ../pat_tab/mainwindow.cpp:1: /usr/include/qt5/QtCore/qobject.h:196:36: note: static QMetaObject::Connection QObject::connect(const QObject*, const char*, const QObject*, const char*, Qt::ConnectionType) static QMetaObject::Connection connect(const QObject *sender, const char *signal, ^ /usr/include/qt5/QtCore/qobject.h:196:36: note: no known conversion for argument 2 from '<unresolved overloaded function type>' to 'const char*' /usr/include/qt5/QtCore/qobject.h:199:36: note: static QMetaObject::Connection QObject::connect(const QObject*, const QMetaMethod&, const QObject*, const QMetaMethod&, Qt::ConnectionType) static QMetaObject::Connection connect(const QObject *sender, const QMetaMethod &signal, ^ /usr/include/qt5/QtCore/qobject.h:199:36: note: no known conversion for argument 2 from '<unresolved overloaded function type>' to 'const QMetaMethod&' /usr/include/qt5/QtCore/qobject.h:475:32: note: QMetaObject::Connection QObject::connect(const QObject*, const char*, const char*, Qt::ConnectionType) const inline QMetaObject::Connection QObject::connect(const QObject *asender, const char *asignal, ^ /usr/include/qt5/QtCore/qobject.h:475:32: note: no known conversion for argument 2 from '<unresolved overloaded function type>' to 'const char*' /usr/include/qt5/QtCore/qobject.h:213:43: note: template<class Func1, class Func2> static QMetaObject::Connection QObject::connect(const typename QtPrivate::FunctionPointer<Func>::Object*, Func1, const typename QtPrivate::FunctionPointer<Func2>::Object*, Func2, Qt::ConnectionType) static inline QMetaObject::Connection connect(const typename QtPrivate::FunctionPointer<Func1>::Object *sender, Func1 signal, ^ /usr/include/qt5/QtCore/qobject.h:213:43: note: template argument deduction/substitution failed: ../pat_tab/mainwindow.cpp:99:74: note: couldn't deduce template parameter 'Func1' connect(spinBoxUtc, &QSpinBox::valueChanged, this, &MainWindow::fillData); ^ In file included from /usr/include/qt5/QtWidgets/qwidget.h:38:0, from /usr/include/qt5/QtWidgets/QWidget:1, from ../pat_tab/mainwindow.h:4, from ../pat_tab/mainwindow.cpp:1: /usr/include/qt5/QtCore/qobject.h:245:13: note: template<class Func1, class Func2> static typename QtPrivate::QEnableIf<((int)(QtPrivate::FunctionPointer<Func2>::ArgumentCount) >= 0), QMetaObject::Connection>::Type QObject::connect(const typename QtPrivate::FunctionPointer<Func>::Object*, Func1, Func2) connect(const typename QtPrivate::FunctionPointer<Func1>::Object *sender, Func1 signal, Func2 slot) ^ /usr/include/qt5/QtCore/qobject.h:245:13: note: template argument deduction/substitution failed: ../pat_tab/mainwindow.cpp:99:74: note: candidate expects 3 arguments, 4 provided connect(spinBoxUtc, &QSpinBox::valueChanged, this, &MainWindow::fillData); ^ In file included from /usr/include/qt5/QtWidgets/qwidget.h:38:0, from /usr/include/qt5/QtWidgets/QWidget:1, from ../pat_tab/mainwindow.h:4, from ../pat_tab/mainwindow.cpp:1: /usr/include/qt5/QtCore/qobject.h:254:13: note: template<class Func1, class Func2> static typename QtPrivate::QEnableIf<(((int)(QtPrivate::FunctionPointer<Func2>::ArgumentCount) >= 0) && (! QtPrivate::FunctionPointer<Func2>::IsPointerToMemberFunction)), QMetaObject::Connection>::Type QObject::connect(const typename QtPrivate::FunctionPointer<Func>::Object*, Func1, const QObject*, Func2, Qt::ConnectionType) connect(const typename QtPrivate::FunctionPointer<Func1>::Object *sender, Func1 signal, const QObject *context, Func2 slot, ^ /usr/include/qt5/QtCore/qobject.h:254:13: note: template argument deduction/substitution failed: ../pat_tab/mainwindow.cpp:99:74: note: couldn't deduce template parameter 'Func1' connect(spinBoxUtc, &QSpinBox::valueChanged, this, &MainWindow::fillData); ^ In file included from /usr/include/qt5/QtWidgets/qwidget.h:38:0, from /usr/include/qt5/QtWidgets/QWidget:1, from ../pat_tab/mainwindow.h:4, from ../pat_tab/mainwindow.cpp:1: /usr/include/qt5/QtCore/qobject.h:285:13: note: template<class Func1, class Func2> static typename QtPrivate::QEnableIf<(QtPrivate::FunctionPointer<Func2>::ArgumentCount == (-1)), QMetaObject::Connection>::Type QObject::connect(const typename QtPrivate::FunctionPointer<Func>::Object*, Func1, Func2) connect(const typename QtPrivate::FunctionPointer<Func1>::Object *sender, Func1 signal, Func2 slot) ^ /usr/include/qt5/QtCore/qobject.h:285:13: note: template argument deduction/substitution failed: ../pat_tab/mainwindow.cpp:99:74: note: candidate expects 3 arguments, 4 provided connect(spinBoxUtc, &QSpinBox::valueChanged, this, &MainWindow::fillData); ^ In file included from /usr/include/qt5/QtWidgets/qwidget.h:38:0, from /usr/include/qt5/QtWidgets/QWidget:1, from ../pat_tab/mainwindow.h:4, from ../pat_tab/mainwindow.cpp:1: /usr/include/qt5/QtCore/qobject.h:293:13: note: template<class Func1, class Func2> static typename QtPrivate::QEnableIf<(QtPrivate::FunctionPointer<Func2>::ArgumentCount == (-1)), QMetaObject::Connection>::Type QObject::connect(const typename QtPrivate::FunctionPointer<Func>::Object*, Func1, const QObject*, Func2, Qt::ConnectionType) connect(const typename QtPrivate::FunctionPointer<Func1>::Object *sender, Func1 signal, const QObject *context, Func2 slot, ^ /usr/include/qt5/QtCore/qobject.h:293:13: note: template argument deduction/substitution failed: ../pat_tab/mainwindow.cpp:99:74: note: couldn't deduce template parameter 'Func1' connect(spinBoxUtc, &QSpinBox::valueChanged, this, &MainWindow::fillData); ^ Makefile:653: recipe for target 'mainwindow.o' failed make: *** [mainwindow.o] Error 1 09:02:52: The process "/usr/bin/make" exited with code 2. Error while building/deploying project pat_tab (kit: QT5.6.1) When executing step "Make" 09:02:52: Elapsed time: 00:02.
Then I googled for a solution and found out to replace the connect statement with this which seems to work:
connect(spinBoxUtc, static_cast<void(QSpinBox::*)(int)>(&QSpinBox::valueChanged), this, &MainWindow::fillData);
Can someone explain what this does and why all other connect statements in my code (see below) are working exept those that use a "valueChanged" ?
... connect(comboBoxTime, &QComboBox::currentTextChanged, this, &MainWindow::fillData); connect(timeEditPolarisRa, &QTimeEdit::timeChanged, this, &MainWindow::fillData); connect(dateTimeEditCurrentTime, &QDateTimeEdit::dateTimeChanged, this, &MainWindow::fillData); ...
-
Hi,
Do you have several fillData methods ?Mis-read...
-
The 'connect' needs at argument 2 and 4 a function pointer.
Here in your compiler message you see some
note: no known conversion for argument 2 from '<unresolved overloaded function type>
That means argument 2 is overloaded, so that the compiler needs the exact signature for determining the exact method. So you give it this hint with your static cast.The signature of a pointer to a method is:
return_type (class_name::*)(argument_type1, ...)
The points of matter are the argument's types, that's needed for determining the right method.If your methods are not overloaded, you can omit the cast, due this methods are unambiguous.
-
You can also use (Qt 5.7+):
qOverload<int>(&QSpinBox::valueChanged)
instead of the static cast.
-
static_cast<void (QSpinBox::*)(int)>(&QSpinBox::valueChanged)
is what you need. Or the QString version. Which one doesn't matter since you don't use the argument.Starting with Qt 5.7 you can use qOverload.
-
Ok thank you all!
Its still a bit unclear to me, why does QSpinBox::valueChanged differ so much to the comiler to lets say
&QComboBox::currentTextChanged? What makes "valueChanged" an overloaded function and "currentTextChanged" not? -
Oh well, I see http://doc.qt.io/qt-5/qspinbox.html
Signals void valueChanged(int i) void valueChanged(const QString &text)
<--rtfm! Its now clear to me :)
7/7