【问题标题】:QT even processing while waitForConnected is running在 waitForConnected 运行时 QT 甚至处理
【发布时间】:2015-01-05 20:12:08
【问题描述】:

我有一个循环应该尝试从范围连接到每个 IP:

for(...){

socket->connectToHost(addres,port);
do stuff....
if(socket->waitForConnected(2000))
{
do stuff...
  if(socket->waitForReadyRead(1000))
  {
   do stuff...
  }
  else do stuff...
}
do stuff ......
}

在连接尝试期间 UI 冻结,因为在此期间没有事件处理。我试图添加 QCoreApplication::processEvents();在循环内部,但是在waitForConnected期间它仍然会冻结很长时间,我也尝试使用计时器,但这也不起作用,因为QT首先需要事件处理才能使用计时器。有什么方法可以在连接期间提供事件处理(防止 UI 冻结),或者为 waitForConnection 使用一些非阻塞替代方案?

【问题讨论】:

  • 你为什么不使用适当的信号,比如readyRead,在这种情况下你的GUI不会被冻结。

标签: c++ qt sockets event-handling


【解决方案1】:

最好的方法是在异步模式下使用QTcpSocket,通过将套接字的信号连接到相关插槽:

connect( socket, SIGNAL(connected()), this, SLOT(onConnected()) );
connect( socket, SIGNAL(readyRead()), this, SLOT(tcpReady()) );
connect( socket, SIGNAL(error(QAbstractSocket::SocketError)),
    this, SLOT(tcpError(QAbstractSocket::SocketError)) );

并在插槽中处理您的应用程序逻辑:

void MyClass::onConnected()
{
    ...
}
void MyClass::tcpError(QAbstractSocket::SocketError error)
{
    ...
}

您还可以使用QEventLoop 使用本地事件循环,并将QTcpSocket 的信号connectederror、...连接到QEventLoop 的退出槽。这样,当套接字连接或发生错误时,本地事件循环退出并执行其余的:

socket->connectToHost(addres,port);

QEventLoop loop;
loop.connect(socket, SIGNAL(connected()), SLOT(quit())); 
loop.connect(socket, SIGNAL(error(QAbstractSocket::SocketError)), SLOT(quit())); 
loop.exec();

//...

我不应该认为这是“阻塞等待而不阻塞 UI”的标准模式。

【讨论】:

    【解决方案2】:

    请写出 100 次“我不能在 GUI 事件处理程序中等待”。

    使用异步信号或断开通信。

    【讨论】:

    • 你能写出更多关于异步信号的东西吗?与普通信号相比,它们有什么不同?以及如何创建其中之一?
    猜你喜欢
    • 2020-03-01
    • 2021-03-17
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-12-04
    • 2020-02-02
    相关资源
    最近更新 更多