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);
    ...
    

  • Lifetime Qt Champion

    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.


  • Qt Champions 2017

    You can also use (Qt 5.7+):

    qOverload<int>(&QSpinBox::valueChanged)
    

    instead of the static cast.


  • Lifetime Qt Champion

    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 :)



Looks like your connection to Qt Forum was lost, please wait while we try to reconnect.