0

所以,我试图在 Qt 中运行一些简单的代码来返回给定网页的内容。经过快速研究,我能够开发自己的课程来简化流程:

WebFetch::WebFetch()
{
    nam = new QNetworkAccessManager(this);
    connect(nam, SIGNAL(finished(QNetworkReply*)), this, SLOT(finished(QNetworkReply*)));
}

QString WebFetch::get(QString url)
{
    nam->get(QNetworkRequest(QUrl(url)));
}

void WebFetch::finished(QNetworkReply* reply)
{
    QByteArray data = reply->readAll();
    QString str(data);
}

但是,我在上面的代码中发现的一个大问题是调用是异步的。我希望“get”函数在检索到字符串后简单地返回字符串,这似乎是不可能的,因为它需要等待完成的信号,此时无法让“get”返回检索到的任何内容由“完成”插槽。是否有上述方法的替代方法,或者有没有一种方法可以让“get”返回“finished”检索到的内容?任何帮助将不胜感激。谢谢!

4

1 回答 1

0

The call being asynchronous is not a problem - it's a big win. With a synchronous call, you're essentially wasting potentially hundreds ok KB of RAM, and an entire thread, just idly waiting for something to come back. You can't write such code while pretending that things happen synchronously or even "quickly" for that matter. I won't even comment on the insanity of running such synchronous code in the GUI thread. It's also a very bad idea to run a local event loop, since suddenly all of your GUI code becomes reentrant. My bet is that you neither design nor test for that.

You have to break down whatever code is expecting the result into two parts: the first part needs to place the request. The second part, in a slot, is notified when the request is finished and continues doing whatever is to be done.

If you wish to have it all in a single method, use C++11:

QNetworkAccessManager * mgr = ...;
QObject::connect(mgr, &QNetworkAccessManager::finished, 
[this, mgr](QNetworkReply * reply){
  // here you can do things with the reply
});
mgr->get(QNetworkRequest("....");

For a complete example, see this 300-line photographic mosaic generator that pulls random images from imgur. It extensively uses asynchronous, multithreaded processing and lambdas in the above style.

于 2014-04-21T22:39:42.690 回答