2012-05-08 106 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線程暫停的影響。