简体   繁体   中英

C++/Qt - Signal from one thread to another threads slot

I am setting up a client working with QTcpSocket . The part where the connection to the server is set is to implement as a thread.

This is how my class looks like, which implements the connection functions (.hpp):

class Connector: public QObject {
Q_OBJECT
public:
Connector(QString hexHost);
virtual ~Connector();

// Start to establish a connection
void startConnection();
// End thread
void stopConnection();

signals:
// Emitted, if connector should get to work
void startTransforming();
// Emitted, if transformation from hex to dig is complete
void transformationFinished();
// Emitted, if connection is established
void connectionEstd();
// Emitted, if connection failed
void connectionFailed();
// Emitted, if work is done
void doneConnecting();

public slots:
// Connect to server
void connectToServer();

private:
// IP of the server
QString addressHost;
// Socket
QTcpSocket aQTcpSocket;
};

And this is how I implemented this class (.cpp);

Connector::Connector(QString hexHost)
{
// Save user data
addressHost = hexHost;

// Start thread
bool result = QObject::connect(this, SIGNAL(startTransforming()), this, SLOT(transformIP()));
Q_ASSERT(result);

// Start trying to establish a connection
result = QObject::connect(this, SIGNAL(transformationFinished()), this, SLOT(connectToServer()));
Q_ASSERT(result);

// End thread
result = QObject::connect(this, SIGNAL(doneConnecting()), this, SLOT(deleteLater()));
Q_ASSERT(result);
Q_UNUSED(result);
}

Connector::~Connector()
{
QObject::disconnect(this, SIGNAL(startTransforming()), this, SLOT(transformIP()));
QObject::disconnect(this, SIGNAL(transformationFinished()), this, SLOT(connectToServer()));
QObject::disconnect(this, SIGNAL(doneConnecting()), this, SLOT(deleteLater()));
}

void Connector::transformIP()
{
[...]

// Emit ready signal
emit transformationFinished();
}

void Connector::connectToServer()
{
aQTcpSocket.connectToHost(addressHost, port);
    result = aQTcpSocket.waitForConnected(5000);

    if(result)
{
    emit connectionFailed();
    emit doneConnecting();
        std::clog << "Connection failed!" << std::endl;   // This debug message is printed during runtime
    return;
    }

// Emit signal
emit connectionEstd();
}

void Connector::startConnection()
{
emit startTransforming();
}

void Connector::stopConnection()
{
emit doneConnecting();
}

I start the thread by:

[...]

// Create new thread
QThread *conThread = new QThread();
// Create connector object
aConnector = new Connector(hexHost);
aConnector->moveToThread(conThread);
conThread->start();

// Clean up thread
bool result = QObject::connect(aConnector, SIGNAL(destroyed()), conThread, SLOT(quit()));
Q_ASSERT(result);

result = QObject::connect(conThread, SIGNAL(finished()), conThread, SLOT(deleteLater()));
Q_ASSERT(result);

// Connect signals
result = QObject::connect(aConnector, SIGNAL(connectionFailed()), this, SLOT(onConnectionFailed()));
Q_ASSERT(result);

result = QObject::connect(aConnector, SIGNAL(connectionEstd()), this, SLOT(onConnectionEstd()));
Q_ASSERT(result);
Q_UNUSED(result);

// Get connector to work
aConnector->startConnection();

[...]

When i test the program, the connector is created correctly. He starts the function transformIP() and connectToServer(). Currently i do not have a server running, so the client is not able to connect. This should result in emitting the signal connectionFailed() The client class, which starts the thread with the connector object, should receive this signal and should react on it.

The problem is: The signal does not seem to be emitted, because the client class does not react on it. Here is the part in the client class, where i connect the signal to a certain slot:

 // Connect signals
result = QObject::connect(aConnector, SIGNAL(connectionFailed()), this, SLOT(onConnectionFailed()));
Q_ASSERT(result);

Would be great, if someone had an idea how to solve this, thanks :)

It looks like QTcpSocket.connectToHost return value is void and the call is asynchronous. What you need to do, is to call QTcpSocket.connectToHost() and wait for the connection to finish using QTcpSocket.waitForConnected( CONNECT_TIME_OUT ) and have else handle the bad connection

Example:

QTcpSocket socket;
socket.connectToHost(QHostAddress("172.0.0.1", 8080);
if (!socket.waitForConnected(5000)) {
    emit connectionFailed();
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM