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
-
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