【问题标题】:Loading file over http通过http加载文件
【发布时间】:2012-05-08 17:59:13
【问题描述】:

我是QT新手,遇到以下问题。

下载返回一个空文件:

QFile file("book.gif"); 
QHttp http; 
if (file.open(QIODevice::WriteOnly))
{ 
    http.setHost("www.geocities.com"); 
    http.get("/mslerm/images/qtbook.gif", &file); 
    http.close(); 
    file.close(); 
}

但如果在关闭 http 调用消息框之前 - 一切正常:

QFile file("book.gif"); 
QHttp http; 
if (file.open(QIODevice::WriteOnly))
{ 
    http.setHost("www.geocities.com"); 
    http.get("/mslerm/images/qtbook.gif", &file);
    QMessageBox msgBox;
    msgBox.setText(http.errorString());
    msgBox.exec();
    http.close(); 
    file.close(); 
}

有什么想法吗?

【问题讨论】:

    标签: c++ file qt http


    【解决方案1】:

    问题在于 get() 方法是非阻塞的,如文档本身所述: Qhttp.get

    一种方法是将 QHttp::dataReadProgress signal 与您开发的 slot 连接起来,您可以在其中处理从QHttp 对象。 还要记住,QHttp 和 QFtp 类现在都已弃用,建议使用的类是:

    QNetworkAccessManager
    QNetworkRequest
    QNetworkReply

    【讨论】:

    • 感谢您的详细回复
    【解决方案2】:

    您应该将一些回调连接到 QHttp 完成信号并在那里关闭文件处理程序。当您创建一个消息框时,从它弹出到您关闭它的时间可能足以让下载结束,然后您正确关闭文件处理程序。关键是QMessageDialog::exec方法是同步的。

    【讨论】:

      【解决方案3】:

      消息框在其 exec() 中旋转一个事件循环,并允许 QHttp 的异步处理发生。事件循环必须有机会在开始传输和期待任何结果之间运行。

      理想情况下,您应该在连接到 QHttp 的requestFinished(...) 信号的插槽中开始传输并处理结果。传输开始后,您的代码必须返回事件循环。

      作为一种快速破解方法,您可以调用QCoreApplication::processEvents(QEventLoop::AllEvents, time),其中 time 是您希望 http 传输花费的最大毫秒数。这将被认为是不良风格并产生负面影响。一方面,可以重新输入开始传输的代码——例如,如果您在按钮单击槽中启动传输,并且用户在传输完成之前再次单击它。

      您应该采用异步的、基于事件的编程风格,其中您有一个请求/响应函数链:请求函数启动可能需要时间的事情,而响应函数处理结果。这听起来可能很乏味,但它是生成响应式应用程序的唯一方法。这样的代码通常驻留在 QObject 中,如果所有处理都是通过信号/槽连接处理事件完成的(但不是直接调用槽!),它可以很容易地移动到另一个线程进一步提高性能并减少混合谱系的 GUI 线程暂停的影响。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2011-07-18
        • 1970-01-01
        • 2010-09-06
        • 1970-01-01
        • 2015-03-25
        相关资源
        最近更新 更多