c++ - Qt 槽调用两次

标签 c++ multithreading qt sockets signals-slots

mainwindow 中有一个插槽 MainWindow::establish_connection,我试图在其中调用不同线程中的 Server::establish_connection:

void MainWindow::establish_connection(const std::string& nickname,
                                      const std::string& ip, int port)
{ 
    auto thread = new QThread(this);
    remote_server = new Server(nickname, ip, port);

    connect(thread, SIGNAL(started()), remote_server, SLOT(establish_connection()));

    connect(remote_server, SIGNAL(connected()), this, SLOT(connection_established()));

    connect(remote_server, SIGNAL(readyRead()), this, SLOT(handle_reply()));

    connect(remote_server, SIGNAL(error(QAbstractSocket::SocketError)), this,
            SLOT(connection_failed(QAbstractSocket::SocketError)));

    connect(remote_server, SIGNAL(stop_thread()), thread, SLOT(quit()));

    thread->start();
}

Server::establish_connection 方法:

void Server::establish_connection()
{
    master_socket = std::move(
                std::unique_ptr<QTcpSocket>(new QTcpSocket(nullptr)));

    connect(master_socket.get(), SIGNAL(connected()), SIGNAL(connected()));

    connect(master_socket.get(), SIGNAL(readyRead()), SIGNAL(readyRead()));
    connect(master_socket.get(), SIGNAL(error(QAbstractSocket::SocketError)),
            SIGNAL(error(QAbstractSocket::SocketError)));

    master_socket->connectToHost(ip.c_str(), port);
    if (!master_socket->waitForConnected(timeout*1000))
    {
        emit error(master_socket->error());

    }
    emit stop_thread();
}

但是当 error 信号发出时,MainWindow::connection_failed 调用两次。

void MainWindow::connection_failed(QAbstractSocket::SocketError e)
{
    QString err_msg = remote_server->get_socket()->errorString();

    qDebug() << err_msg;
}

输出:

"Connection refused"
"Connection refused"

如何防止这个问题?

最佳答案

在这里你从 master_socket 重新发出信号错误:connect(master_socket.get(), SIGNAL(error(QAbstractSocket::SocketError)), SIGNAL(错误(QAbstractSocket::SocketError)));

这对我来说似乎是第一位的。

在这里你在超时后自己发出它:

if (!master_socket->waitForConnected(timeout*1000))
{
    emit error(master_socket->error());

}

这似乎是你的第二名。

我认为当您等待超时 error() 时,它已经被您的 connect() 发出并转发。之后你又自己发射它。这看起来 super 流畅。

测试删除此显式发出是否对您有用。

或者你可以把行 connect(master_socket.get(), SIGNAL(error(QAbstractSocket::SocketError)), SIGNAL(error(QAbstractSocket::SocketError))); 在您的 if 条件之后获取从那一点开始的所有错误。无需断开连接。

或者将它放在 else 分支中,因为如果可以建立连接,您只对更多错误感兴趣:

if (!master_socket->waitForConnected(timeout*1000))
{
    emit error(master_socket->error());

} else {

   connect(master_socket.get(), SIGNAL(error(QAbstractSocket::SocketError)),
        SIGNAL(error(QAbstractSocket::SocketError)));
}

两者都应该有效。

关于c++ - Qt 槽调用两次,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34183669/

相关文章:

c# - GetConsumingEnumerable() 生产者-消费者的多线程 BlockingCollection 替代方案

python - 通过glUnproject从鼠标坐标到世界坐标

c++ - 具有集体功能的 MPI 死锁

c++ - 我如何处理队列前端和弹出功能

Python:以固定间隔连续且可取消地重复执行

C# TCP 聊天应用线程

qt - 我如何在 Qt 或 CQA 中使用 openssl for symbian?

c++ - QObject::connect: 没有这样的信号(类名)(信号名)(atribure)

c++ - 函数调用运算符重载的参数太多

c++ - 使用 Windows Imaging Component 将 EMF 转换为 BMP(元文件到位图)