最近我使用QTE开发PDA程序,在PDA程序中需要通过HTTP协议访问WEB服务端获取数据,但发现QHttp这个类提供的机制是异步的,但我们需同步的功能,在获取到服务端的数据后再进行一步的处理,于是我们这样写了程序:
QHttp* http = new QHttp();
connect(http, SIGNAL(requestFinished(int, bool)), this, SLOT(onRequestFinished(int, bool)));
http->setHost("...");
....
QBuffer buffer;
m_post_id = http->post(path, data, &buffer);
wait();
// wait()方法的实现
void wait()
{
m_finished_flag = false; // 这是一个成员变量,标示请求是否完成
while(!m_finished_flag )
{
QApplication::processEvent();
}
}
// QHttp requestFinished信号槽
void onRequestFinished(int requestID , bool)
{
if (requestID == m_post_id)
{
m_finished_flag = true;
}
}
大体是这样完成的,在PC机上这段程序可以完成同步服务,但到PDA就无法实现,在post发出请求后wait()方法就进行死循环了。
经过一段时间的研究,我们发现在QTE下,推荐使用QNetworkAccessManager这个类,并且QTE下还提供了QEventLoop这个类用来使程序进入到主程序框架中的事件循环中,这样我们就不用自已写While语名来等待网络通信的完成信号了,于我们将原来上面的程序段改为一下的程序段:
QNetworkAccessManager* net_manager = new QNetworkAccessManager(parent);
QEventLoop el;
QTimer timer;
timer.setSingleShot(true);
connect(net_manager, SIGNAL(finished(QNetworkReply*)), &el, SLOT(quit()));
connect(&timer, SIGNAL(timeout()), &el, SLOT(quit())); // 超时也退出事件循环
QUrl url("http://YouWebServer:port/path...");
QNetworkRequest request(url);
net_manager->post(request, data);
el.exec();
if (timer.isActive())
{
// 到这里说明请求完成了
}
else
{
// 到这里说明等待超时了
}