1

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

有任何想法吗?

4

3 回答 3

4

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

一种方法是将QHttp::dataReadProgress 信号与您开发的插槽连接起来,您可以在其中处理从 QHttp 对象接收到的数据。还要记住,现在不推荐使用 QHttp 和 QFtp 类,建议使用的类是:

QNetworkAccessManager
QNetworkRequest
QNetworkReply

于 2012-05-08T18:11:27.323 回答
3

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

于 2012-05-08T18:04:22.567 回答
0

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

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

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

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

于 2012-05-08T22:43:10.700 回答