QObect::connect call does not compile



  • Hello,

    When calling QObject::connect I face problems that I cannot undertsand, even though I have used the signal/slots mechanisms many times witout issues.

    I was in the process of writing a very simple TCP Client. At some point I added slots with names like "connect" and I think thats when things started to go wrong.

    Here are the things that I checked before asking for help:

    • Class header file is including QObject and header file is included in the class source file
    • Class inherit from QObject
    • Class uses the Q_OBJECT
    • The project .pro file includes "network"

    I checked many other things but here are the most obvious. Complete code can be found below

    TcpClient.h

    #ifndef TCPCLIENT_H
    #define TCPCLIENT_H
    
    #include <QObject>
    #include <QTcpSocket>
    
    class TcpClient : public QObject
    {
        Q_OBJECT
    
    public:
        explicit TcpClient();
        /* Received from the HMI. Connect to the server */
        void myFunctionToConnect(QString IP_received);
        /* Received from the HMI. Write on the socket */
        void send_text(QString text);
    
    public slots:
        /* From the socket. Emit signal to the HMI */
        void connection_OK();
        /* From the socket. Read the socket and emit signal to the HMI */
        void read();
    
    signals:
        void to_HMI_connection_OK();
        void to_HMI_update_text(QString);
    
    private:
        QString IP;
        int port;
        QTcpSocket socket;
    };
    
    #endif // TCPCLIENT_H
    
    

    TcpClient.c

    #include "tcpclient.h"
    
    #include <QTextStream>
    
    
    TcpClient::TcpClient()
    {
        port = 2000;
        /* Signal emitted when the client is connected to a server */
        QObject::connect(&socket, SIGNAL(connected()), this, SLOT(connection_OK()));
    
        /* Signal emitted when data have is received and is ready to be read */
        QObject::connect(&socket, SIGNAL(readyRead()), this, SLOT(read()));
    }
    
    void TcpClient::myFunctionToConnect(QString IP_received)
    {
        IP = IP_received;
        socket.connectToHost(IP, port);
    }
    
    void TcpClient::send_text(QString text)
    {
        /* Create a stream and associate it to the socket */
        QTextStream stream(&socket);
        /* Write in the stream the text input from the HMI */
        stream << text << endl;
    }
    
    void TcpClient::connection_OK()
    {
        /* Send signal to HMI to update the connection status */
        emit to_HMI_connection_OK();
    }
    
    void TcpClient::read()
    {
        QString line;
        while(socket.canReadLine()){
            /* Read from the socket the received line */
            line = socket.readLine();
            /* Send signal to HMI to update the received text from the socket */
            emit to_HMI_update_text(line);
        }
    }
    

    The two not-compiling lines are:
    QObject::connect(&socket, SIGNAL(connected()), this, SLOT(connection_OK()));
    and
    QObject::connect(&socket, SIGNAL(readyRead()), this, SLOT(read()));

    This is what I get from the console when compiling (only an extract):

    ..\SocketClientServer\tcpclient.cpp: In constructor 'TcpClient::TcpClient()':
    ..\SocketClientServer\tcpclient.cpp:10:79: error: no matching function for call to 'TcpClient::connect(QTcpSocket*, const char*, TcpClient*, const char*)'
         QObject::connect(&socket, SIGNAL(connected()), this, SLOT(connection_OK()));
                                                                                   ^
    In file included from C:/Qt/5.8/mingw53_32/include/QtCore/QObject:1:0,
                     from ..\SocketClientServer\tcpclient.h:4,
                     from ..\SocketClientServer\tcpclient.cpp:1:
    C:/Qt/5.8/mingw53_32/include/QtCore/qobject.h:222:43: note: candidate: 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,
                                               ^
    C:/Qt/5.8/mingw53_32/include/QtCore/qobject.h:222:43: note:   template argument deduction/substitution failed:
    C:/Qt/5.8/mingw53_32/include/QtCore/qobject.h: In substitution of '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) [with Func1 = const char*; Func2 = const char*]':
    ..\SocketClientServer\tcpclient.cpp:10:79:   required from here
    C:/Qt/5.8/mingw53_32/include/QtCore/qobject.h:222:43: error: no type named 'Object' in 'struct QtPrivate::FunctionPointer<const char*>'
    C:/Qt/5.8/mingw53_32/include/QtCore/qobject.h:254:13: note: candidate: 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)
                 ^
    C:/Qt/5.8/mingw53_32/include/QtCore/qobject.h:254:13: note:   template argument deduction/substitution failed:
    ..\SocketClientServer\tcpclient.cpp:10:79: note:   candidate expects 3 arguments, 4 provided
         QObject::connect(&socket, SIGNAL(connected()), this, SLOT(connection_OK()));
    

    I have spent more than two hours on this, please tell me it's not obvious =)



  • I think you need to add the QObject constructor to your constructor:

    TcpClient::TcpClient()
    : QObject()
    {
    //rest of your constructor goes here
    }

  • Qt Champions 2017

    It appears the overload resolution got all scrambled up with the template instantiation. You should migrate to the pointer-to-member syntax anyway, so I'd suggest that to be the first thing you do:

    QObject::connect(&socket, &QTcpSocket::connected, this, &TcpClient::connection_OK);
    QObject::connect(&socket, &QTcpSocket::readyRead, this, &TcpClient::read);
    

    As a side note, you should make it a habit to support the QObject tree through the constructors of your derived classes, and to set the appropriate parent for your members:

    TcpClient::TcpClient(QObject * parent)
        : QObject(parent), port(2000), socket(this)
    {
    }
    


  • @CynaCons ,

    I tried your example in Qt 5.7(msvc). It is compiling.



  • Adding the QObject constructor to my class's constructor and adding the pointer-to-member syntax suggested by Kshegunov fixed the issue.

    Thanks guys and good day.



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