Important: Please read the Qt Code of Conduct - https://forum.qt.io/topic/113070/qt-code-of-conduct

Qt6 signals and slots connect issue



  • I am trying to make a very simple example using Qt6 with the new signals/slots syntax using functors. However, the compiler just does not accept the change. Using old syntax SIGNAL()/SLOT() works like a charm. To reproduce the error, proceed as described.

    Create a simple example with just an horizontalSlider and a LCDNumber on a Qt Designer Form. Connect the "valueChanged(int)" signal from the horizontalSlider with the "display(int)" slot on the LCDNumber using the signal/slots edit tool and compile it.

    It produces the following error messages:

    In file included from ../../untitled5/mainwindow.cpp:2:
    ./ui_mainwindow.h:56:18: error: no matching member function for call to 'connect'
            QObject::connect(horizontalSlider, &QSlider::valueChanged, lcdNumber, &QLCDNumber::display);
            ~~~~~~~~~^~~~~~~
    ../../../Qt/6.1.1/gcc_64/include/QtCore/qobject.h:195:36: note: candidate function not viable: no known conversion from 'void (QAbstractSlider::*)(int)' to 'const char *' for 2nd argument
        static QMetaObject::Connection connect(const QObject *sender, const char *signal,
                                       ^
    ../../../Qt/6.1.1/gcc_64/include/QtCore/qobject.h:198:36: note: candidate function not viable: no known conversion from 'void (QAbstractSlider::*)(int)' to 'const QMetaMethod' for 2nd argument
        static QMetaObject::Connection connect(const QObject *sender, const QMetaMethod &signal,
                                       ^
    ../../../Qt/6.1.1/gcc_64/include/QtCore/qobject.h:441:41: note: candidate function not viable: no known conversion from 'Ui_MainWindow' to 'const QObject' for object argument
    inline QMetaObject::Connection QObject::connect(const QObject *asender, const char *asignal,
                                            ^
    ../../../Qt/6.1.1/gcc_64/include/QtCore/qobject.h:215:43: note: candidate template ignored: couldn't infer template argument 'Func2'
        static inline QMetaObject::Connection connect(const typename QtPrivate::FunctionPointer<Func1>::Object *sender, Func1 signal,
                                              ^
    ../../../Qt/6.1.1/gcc_64/include/QtCore/qobject.h:256:13: note: candidate template ignored: couldn't infer template argument 'Func2'
                connect(const typename QtPrivate::FunctionPointer<Func1>::Object *sender, Func1 signal, const QObject *context, Func2 slot,
                ^
    ../../../Qt/6.1.1/gcc_64/include/QtCore/qobject.h:295:13: note: candidate template ignored: couldn't infer template argument 'Func2'
                connect(const typename QtPrivate::FunctionPointer<Func1>::Object *sender, Func1 signal, const QObject *context, Func2 slot,
                ^
    ../../../Qt/6.1.1/gcc_64/include/QtCore/qobject.h:247:13: note: candidate function template not viable: requires 3 arguments, but 4 were provided
                connect(const typename QtPrivate::FunctionPointer<Func1>::Object *sender, Func1 signal, Func2 slot)
                ^
    ../../../Qt/6.1.1/gcc_64/include/QtCore/qobject.h:287:13: note: candidate function template not viable: requires 3 arguments, but 4 were provided
                connect(const typename QtPrivate::FunctionPointer<Func1>::Object *sender, Func1 signal, Func2 slot)
                ^
    ../../dca1202/untitled5/mainwindow.cpp:10:12: error: no matching member function for call to 'connect'
      QObject::connect(ui->horizontalSlider, &QAbstractSlider::valueChanged,
      ~~~~~~~~~^~~~~~~
    ../../../Qt/6.1.1/gcc_64/include/QtCore/qobject.h:195:36: note: candidate function not viable: no known conversion from 'void (QAbstractSlider::*)(int)' to 'const char *' for 2nd argument
        static QMetaObject::Connection connect(const QObject *sender, const char *signal,
                                       ^
    ../../../Qt/6.1.1/gcc_64/include/QtCore/qobject.h:198:36: note: candidate function not viable: no known conversion from 'void (QAbstractSlider::*)(int)' to 'const QMetaMethod' for 2nd argument
        static QMetaObject::Connection connect(const QObject *sender, const QMetaMethod &signal,
                                       ^
    ../../../Qt/6.1.1/gcc_64/include/QtCore/qobject.h:441:41: note: candidate function not viable: no known conversion from 'void (QAbstractSlider::*)(int)' to 'const char *' for 2nd argument
    inline QMetaObject::Connection QObject::connect(const QObject *asender, const char *asignal,
                                            ^
    ../../../Qt/6.1.1/gcc_64/include/QtCore/qobject.h:215:43: note: candidate template ignored: couldn't infer template argument 'Func2'
        static inline QMetaObject::Connection connect(const typename QtPrivate::FunctionPointer<Func1>::Object *sender, Func1 signal,
                                              ^
    ../../../Qt/6.1.1/gcc_64/include/QtCore/qobject.h:256:13: note: candidate template ignored: couldn't infer template argument 'Func2'
                connect(const typename QtPrivate::FunctionPointer<Func1>::Object *sender, Func1 signal, const QObject *context, Func2 slot,
                ^
    ../../../Qt/6.1.1/gcc_64/include/QtCore/qobject.h:295:13: note: candidate template ignored: couldn't infer template argument 'Func2'
                connect(const typename QtPrivate::FunctionPointer<Func1>::Object *sender, Func1 signal, const QObject *context, Func2 slot,
                ^
    ../../../Qt/6.1.1/gcc_64/include/QtCore/qobject.h:247:13: note: candidate function template not viable: requires 3 arguments, but 4 were provided
                connect(const typename QtPrivate::FunctionPointer<Func1>::Object *sender, Func1 signal, Func2 slot)
                ^
    ../../../Qt/6.1.1/gcc_64/include/QtCore/qobject.h:287:13: note: candidate function template not viable: requires 3 arguments, but 4 were provided
                connect(const typename QtPrivate::FunctionPointer<Func1>::Object *sender, Func1 signal, Func2 slot)
    

    The problem becomes more serious because the default connection made by the uic/moc on qt designer automatic generated files. The default connect syntax for Qt6 kits is this new one.

    I am running the examples under Ubuntu 20.10 with gcc 9.3.0. However, some of my students reported the same issue on Windows with the MinGW deployed along with the Qt6 packages.

    What am i doing wrong? Thanks for help and best regards.


  • Lifetime Qt Champion

    @Agostinho You can connect manually like this:

    connect(ui->horizontalSlider, &QSlider::valueChanged, ui->lcdNumber, QOverload<int>::of(&QLCDNumber::display));
    

    See https://doc.qt.io/qt-5/qtglobal.html#qOverload



  • @Agostinho
    You have shown the error messages but not the code causing them.

    In file included from ../../untitled5/mainwindow.cpp:2:

    ./ui_mainwindow.h:56:18: error: no matching member function for call to 'connect'

    Show us the first couple of lines from mainwindow.cpp, and more importantly let's see the ui_mainwindow.h generated.


  • Lifetime Qt Champion

    @JonB said in Qt6 signals and slots connect issue:

    You have shown the error messages but not the code causing them.

    He connects in the designer, not in code



  • @JonB I did not modify the default mainwindow.cpp and mainwindow.h created by qt designer.

    #include "mainwindow.h"
    #include "ui_mainwindow.h"
    #include <QAbstractSlider>
    #include <QLCDNumber>
    MainWindow::MainWindow(QWidget *parent)
      : QMainWindow(parent)
      , ui(new Ui::MainWindow)
    {
      ui->setupUi(this);
    }
    
    MainWindow::~MainWindow()
    {
      delete ui;
    }
    

    In fact, the error is produced on ui_mainwindow.h in the following line:

      QObject::connect(horizontalSlider, &QSlider::valueChanged, lcdNumber, &QLCDNumber::display);
    

    It is just where the new signal/slot connect syntax changes from the old syntax!


  • Lifetime Qt Champion

    @Agostinho The problem is that there are several overloaded versions of the display() slot


  • Lifetime Qt Champion

    @Agostinho You can connect manually like this:

    connect(ui->horizontalSlider, &QSlider::valueChanged, ui->lcdNumber, QOverload<int>::of(&QLCDNumber::display));
    

    See https://doc.qt.io/qt-5/qtglobal.html#qOverload



  • @jsulm said in Qt6 signals and slots connect issue:

    The problem is that there are several overloaded versions of the display() slot

    Thought the same, but can't you select one of them by clicking, when connecting widgets in QtCreator's Design mode?!
    Haven't used it for a long time. And I problably never will. For a reason :)



  • @jsulm I works, but this exact line should be generated automatically by the uic. Should I blame uic? I hope so! :)


  • Lifetime Qt Champion

    @Pl45m4 said in Qt6 signals and slots connect issue:

    Haven't used it for a long time.

    I also don't use Designer to connect signals/slots, so don't know


  • Lifetime Qt Champion

    @Pl45m4 Qt5 uses old connect syntax, so it looks like this:

    QObject::connect(horizontalSlider, SIGNAL(valueChanged(int)), lcdNumber, SLOT(display(int)));
    

    Qt6 seems to use new connect syntax, but I did not check how the generated connect looks like (don't have Qt6 at hand).



  • @jsulm Anyway, thanks for help. Best regards.


Log in to reply