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 2016

    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.


Log in to reply
 

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