C++/Qt-从一个线程到另一个线程槽的信号

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

本文关键字:线程 另一个 信号 一个 Qt- C++      更新时间:2023-10-16

我正在设置一个使用QTcpSocket的客户端。设置到服务器的连接的部分是作为线程实现的。

这就是我的类的样子,它实现了连接函数(.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;
};

这就是我实现这个类(.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();
}

我通过以下方式启动线程:

[...]
// 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();
[...]

当我测试程序时,连接器是正确创建的。他启动函数transformIP()和connectToServer()。目前我没有运行服务器,所以客户端无法连接。这将导致发出信号connectionFailed()用连接器对象启动线程的客户端类应该接收这个信号并对其作出反应

问题是:信号似乎没有被发出,因为客户端类对它没有反应。这是客户端类中的一部分,我将信号连接到某个插槽:

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

如果有人知道如何解决这个问题,那就太好了,谢谢:)

看起来QTcpSocket.connectToHost的返回值是void,调用是异步的。您需要做的是调用QTcpSocket.connectToHost()并等待连接使用QTcpSocket.waitForConnected( CONNECT_TIME_OUT )完成,然后让其他人处理坏连接

示例:

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