QT 甚至在 waitForConnected 运行时处理

QT even processing while waitForConnected is running

我有一个循环,应该尝试连接到范围内的每个 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 使用一些非阻塞替代方法?

请写100遍'I must not wait in GUI event-handlers'。

使用异步信号或关闭通信。

最好的方法是通过将套接字的信号连接到相关插槽,以异步模式使用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 的本地事件循环,并将 connectederror、... 的信号连接到 QTcpSocket 的退出槽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();

//...

我不应该认为这是 "blocking wait without blocking the UI" 的标准模式。