2012-05-08 76 views
1

我是QT新手,遇到以下问题。通过http加载文件

下载返回一个空文件:

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调用的MessageBox之前 - 一切正常:

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(); 
} 

什么想法?

回答

4

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

一种进行的方法是信号与连接QHTTP :: dataReadProgress 插槽您开发处理从QHttp对象接收到的数据的位置。 还记得那两个QHTTP和QFtp类现在过时,建议类使用的是:

QNetworkAccessManager
QNetworkRequest
QNetworkReply

+1

感谢您的详细回复 – mmatviyiv

3

您应该连接一些回调QHTTP结束信号并关闭文件句柄出现。当你创建一个消息框时,它弹出的时间和关闭它的时间可能足以让下载结束,然后正确关闭文件处理程序。关键是QMessageDialog :: exec方法是同步的。

0

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

理想的情况下,就应该开始传输和处理在连接到QHTTP的requestFinished(...)信号时隙的结果。传输开始后,您的代码必须返回到事件循环。

作为一种快速入侵,您可以调用QCoreApplication::processEvents(QEventLoop::AllEvents, time),其中time是您希望进行http传输所需的最大毫秒数。这将被认为是不好的风格,并有消极的后果。例如,开始传输的代码可以重新进入 - 例如,如果您在按钮单击插槽中启动传输,并且用户在传输完成之前再次单击该代码。

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