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":http://doc.qt.digia.com/qq/qq10-signalmapper.html

    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()));
    listServers.append(server);

    return server;
    }

    void ServerManager::serverConnected(QObject *object)
    {
    Server *server = qobject_cast<Server *>(object);
    if(server)
    {
    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

    Thanks


Log in to reply
 

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