1

私は QT を初めて使用し、次の問題に遭遇しました。

Download は空のファイルを返します。

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

続行する1つの方法は、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 転送にかかると予想される最大ミリ秒数です。これはスタイルが悪いと見なされ、悪影響を及ぼします。1 つは、転送を開始するコードを再入力できます。たとえば、ボタン クリック スロットで転送を開始し、転送が完了する前にユーザーがもう一度クリックした場合です。

非同期のイベント ベースのプログラミング スタイルを採用する必要があります。この場合、一連の要求/応答関数があります。要求関数は時間がかかる可能性のある処理を開始し、応答関数は結果を処理します。面倒に聞こえるかもしれませんが、応答性の高いアプリケーションを作成する唯一の方法です。このようなコードは通常 QObject に常駐し、すべての処理がイベントの処理またはシグナル/スロット接続 (スロットの直接呼び出しではない!) によって行われる場合、簡単に別のスレッドに移動してパフォーマンスをさらに向上させ、パフォーマンスを低下させることができます。混合血統の GUI スレッド一時停止の影響。

于 2012-05-08T22:43:10.700 に答える