Cannot connect QSignalMapper to an own object

  • Hello there

    A few days ago I rewrote my application and came to a point, where I need parameters in a SIGNAL/SLOT connection. I found a very helpful article here: "Mapping":

    I made a little test with the subclassing approach, but it's get messy. I cannot use sender(), because the signal is emited by the QTcpSocket and not the object itself (which contains the QTcpSocket)

    This is my server class . It contains the common information about a server connection and the socket:

    @Server::Server(QString hostname, int port, QString username, QObject *parent) : QObject(parent)
    dataHostname = hostname;
    dataPort = port;
    dataUsername = username;
    networkSocket = new QTcpSocket(this);

    QString Server::getHostname()
    return dataHostname;

    int Server::getPort()
    return dataPort;

    QString Server::getUsername()
    return dataUsername;

    QTcpSocket *Server::getSocket()
    return networkSocket;

    Now the plan is to know: When is a socket connected and which object is connected ?

    @// Setup the QSignalMapper
    Network::Network(QObject parent): QObject(parent)
    instanceMapper = new QSignalMapper(this);
    connect(instanceMapper, SIGNAL(mapped(Server
    )), this, SLOT(slotconnected(Server*)));

    // After a server object is created, we call initServer to add the SIGNAL/SLOT connection (QTcpSocket::connected signal)
    void Network::initSocket(Server *server)
    instanceMapper->setMapping(server->getSocket(), server);
    connect(server->getSocket(), SIGNAL(connected()), instanceMapper, SLOT(map()));

    // Slot with the server as parameter
    void Network::slotconnected(Server *server)
    qDebug() << "The server " << server->getHostname() << " is now in connected state";

    This does compile, but after startup:
    Object::connect: No such signal QSignalMapper::mapped(Server*) in /home/simon/Downloads/Client_Qt4/src/libserver/network/Network.cpp:25

    • Exited normally -

    So how can I achieve this ? The QTcpSocket should emit the connected() signal and with the QSignalMapper I should be able to get the server object ?

    Thank you & Nice weekend

  • Moderators

    There are probably more than one solution.
    However, you can connect the signal of QTcpSocket to a signal of your object hosting QTcpSocket.
    Also you can connect the signal to a hosting object's slot and emit again. This may make the QSignalMapper obsolete.

  • Well, the class Server should act as a data object - this means no signals/emits or worker-functions inside this class - they are handled by other classes (like Network)

    How can I understand your second way ?

  • Hello

    I solved the problem. Thery are 2 solutiuons (Please see the question for solution 2 at the end):

    Solution 1: Connecting a QObject to a QSignalMapper and cast back to Server with qobject_cast - I thought something is not possible, but it is:

    @ServerManager::ServerManager(QObject parent) : QObject(parent)
    instanceSignalMapperConnect = new QSignalMapper(this);
    connect(instanceSignalMapperConnect, SIGNAL(mapped(QObject
    )), this, SLOT(serverConnected(QObject*)));

    Server *ServerManager::addServer(QString hostname, int port, QString username)
    Server *server = new Server(hostname, port, username, this);

    instanceSignalMapperConnect->setMapping(server->getSocket(), server);
    connect(server->getSocket(), SIGNAL(connected()), instanceSignalMapperConnect, SLOT(map()));

    return server;

    void ServerManager::serverConnected(QObject *object)
    Server *server = qobject_cast<Server *>(object);
    qDebug() << server->getHostname() << "is now in connected state";

    Solution 2: The first solution generates an overhead (Connect/Disconnect/ReadyRead/Error etc connection) - things get messy, so I switched over to lambdas and C++11:

    @Server *server = new Server("localhost", 9000, "User", this);

    QObject::connect(server->getSocket(), &QTcpSocket::connected, [this, server] ()
    qDebug() << server->getHostname() << "is now connected";
    emit this->signalInThisClass(server);

    But I have one question:Do I have to unconnect the Signal in the lambda connection --> Memory leak ? Or can I leave it that way ? I read something about that, but for me it's not clear


Log in to reply

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