【问题标题】:QLocalSocket - QTimer and LambdaQLocalSocket - QTimer 和 Lambda
【发布时间】:2023-04-08 04:35:02
【问题描述】:

我在 Qt 5.7.1 上对 Lambda 和计时器有一个奇怪的行为。可能是我搞错了。

我用一个套接字开始一个连接,并设置一个计时器来检查它是否在一定时间后连接。

socket连接的信号会停止计时。

但是,通过以下实现,即使调用了 connected 信号,定时器也不会停止。

constructor:

m_connectTimeout.setInterval(5000);

connect(&m_socket, &QLocalSocket::connected, [&]()
{
    // this is called first and should stop the timer.
    m_connectTimeout.stop();
});


connect(&m_connectTimeout, &QTimer::timeout, [&](){
       // this is still called
});

这是在 Qt5.7.1 和 Windows 10 上可重现的问题的最小示例。

#include <QtCore>
#include <QtNetwork>

#define PIPENAME "testbug"

int main(int argc, char *argv[])
{
    QCoreApplication a(argc, argv);

    QTimer timer;
    QLocalSocket socketClient, *socketServer;
    QLocalServer server;
    timer.setInterval(2000);


    QObject::connect(&timer, &QTimer::timeout, [&]
    {
        qDebug() << "client connection timed out";
        timer.stop();
    });

    QObject::connect(&socketClient, &QLocalSocket::connected, [&]
    {
        qDebug() << "client connected";
        timer.stop();
    });

    QObject::connect(&server, &QLocalServer::newConnection, [&]
    {
        qDebug() << "server got connection";
        socketServer = server.nextPendingConnection();
    });

    server.setSocketOptions(QLocalServer::WorldAccessOption);
    server.listen(PIPENAME);

    qDebug() << "client connecting. . .";
    socketClient.connectToServer(PIPENAME, QLocalSocket::ReadWrite);
    timer.start();

    return a.exec();
}

程序的输出:

client connecting. . .
client connected
server got connection
client connection timed out

我还注意到它并不总是可重复的,而且似乎是随机的。

【问题讨论】:

  • m_connectTimeout.stop() 真的运行了吗?设置断点,看是否运行
  • 请尝试提供MCVE。我想不出m_connectTimeout.stop() 不停止计时器的任何原因(您真的确定它首先被调用吗?)。这是一个minimal example,它可以正常工作并且不会重现该问题。
  • @Victor,是的,它确实运行了,我实际上在那里有调试输出。
  • @Mike 完成并编辑
  • @Mike 刚才抱歉,没想到你会这么快

标签: qt lambda qlocalsocket


【解决方案1】:

其实看起来代码是可以的,只是连接太快了,在timer.start之前调用了timer.stop。

在调用连接服务器之前启动计时器似乎可以解决问题

m_timer.start();
m_socketClient.connectToServer(PIPENAME, QLocalSocket::ReadWrite);

这意味着 connectToServer 在后台对事件循环进行一些调用,从而允许调用槽,甚至在执行下一行之前。

【讨论】:

  • 是的,这就是问题所在,我正在写一个答案。 connected() 信号是从 connectToServer() 内部发出的,计时器在您的插槽中停止后启动。
猜你喜欢
  • 2014-12-30
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多