【问题标题】:Network reply after program ends节目结束后网络回复
【发布时间】:2014-08-09 15:07:13
【问题描述】:

我编写了从 url 获取网页源代码的程序,但我遇到了问题,因为当程序结束时,此代码会打印在屏幕上,我无法使用我下载的数据。我认为问题在于程序等待 SIGNAL(finished())。在结束之前有什么方法可以在我的程序中处理下载的数据?

void Get::getCode()
{
    networkManager = new QNetworkAccessManager(this);
    link = "http://example.com/";
    networkManager->get(QNetworkRequest(QUrl(link)));
    connect(networkManager, SIGNAL(finished(QNetworkReply*)), &process, SLOT(replyFinished(QNetworkReply*)));

    //QDesktopServices::openUrl(QUrl(link));
}

...

    void Process::replyFinished(QNetworkReply* pReply)
{
    QString source(pReply->readAll());
    printf("%s\n", source.toStdString().c_str());
}

...

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

    QApplication a(argc, argv);

    Get get; get.getCode();
    MainWindow window;

    printf("test point\n");

    return a.exec();
    //return 0;}

“测试点”首先出现在屏幕上,然后是 html 代码。

【问题讨论】:

  • 您可以将其写入文件吗?
  • 我想在同一个程序中使用这个代码并且不需要写入文件,足够我在 QString 源中写入数据,但是我不能在程序中使用这个变量,因为它在程序结束时获取数据。

标签: c++ qt qnetworkaccessmanager slot


【解决方案1】:

网络管理器异步运行,这意味着您的主线程在调用 get() 方法后立即继续。

您可以通过设置一个等待下载完成的事件循环来解决此问题:

  QEventLoop loop;
  connect(networkManager, SIGNAL(finished()), &loop, SLOT(quit()));
  loop.exec(QEventLoop::ExcludeUserInputEvents);

这应该会给你预期的结果。

【讨论】:

  • 非常感谢,您的代码解决了一半的问题,但我对您的代码有一些疑问。为什么你使用 SLOT(quit())? exec(QEventLoop::ExcludeUserInputEvents) 是什么意思?我也有奇怪的情况,当我使用包含“循环”的函数时,屏幕上总是会打印:“QObject::connect: No such signal QNetworkAccessManager::finished() in...”但之后程序正常工作。最糟糕的是,我仍然无法访问从其他功能下载的数据。
  • quit() 槽用于在网络管理器完成下载后停止事件循环。否则你的程序会在 loop.exec() 调用中永远挂起。 exec() 调用启动本地事件循环。 QEventLoop::ExcludeUserInputEvents 参数告诉您的本地事件循环不处理任何用户输入,例如鼠标/键盘输入。一旦你的本地事件完成,这些输入将被传递到主事件循环,这是你想要的这样一个网络处理事件循环。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2019-09-24
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多