2

API が次のように使用されるライブラリを作成しようとしています。

WebService *service = new WebService( username, password );
User *user = service->getAuthenticatedUser();
UserAssets *assets = user->assets();
// And so on

認証されたユーザーもそのアセットも、WebServerインスタンスの作成時にダウンロードされることはなく、明示的に要求された場合にのみ取得されます。

Qt を使用する前にネットワークからデータを取得する必要があるときはいつでも、finished()信号をQNetworkReply適切なスロットに接続し、そのスロットを使用して返されたデータを処理するという標準的なパターンに従いました。

ここでの問題は、パターンが目的のユースケースに対応していないように見えることです。ライブラリのユーザー (他の開発者) が 1 行を使用して、必要なデータを要求および受信できるようにしたいと考えていますが、「Qt の方法」は、少なくとも私の観点からは、開始する必要があるようです。ある行でリクエストを送信し、信号を別のスロットに接続してデータを取得しますが、これは私が望んでいる経験ではありません。

私は一般的にもQtでもネットワークプログラミングは初めてですが、Pythonで記述されたライブラリを使用し、まったく同じサービスと通信してこれを実現できるため、可能だと思われます。

単一の関数呼び出しで Qt を使用して HTTP 要求のライフサイクル全体を実行することは可能ですか?

4

2 に答える 2

1

あなたの最善の策は、おそらくQEventLoopを使用することです。これにより、1) HTTP 接続を開始し、呼び出し元の観点からは、2) 応答を受け取るまで効果的にブロックすることができます。

例えば:

于 2012-09-01T23:45:35.637 に答える
0

QEventLoopすでに他の人が述べたように、待機finished()またはerror()シグナル、および終了イベントループに使用できます。作業中のこのソリューションには、いくつかの重大な欠点があります。

特定のアドレスをダウンロードするのに時間がかかる場合は、イベント ループにかなりの時間とどまっている可能性があります。イベント ループはイベントを適切に処理しているため、アプリがフリーズすることはありませんが、いずれにせよいくつかの癖があります。ユーザーが読み込みを待っていて、別のボタンを押して別のものを読み込むとします。次に、複数のループインループが発生し、最初のファイルは 2 番目のファイルのダウンロードが完了するまで待機する必要があります。

単一の呼び出しで物事を行うことは、多くのプログラマーに、これが一瞬で起こることを示唆しています。ただし、関数はイベントを内部で処理しているため、これは当てはまらない可能性があります。のようなコードを想像してください

// some pointer accessible to many functions/methods (eg. member, global)
MyData* myData=0;

次に、関数を呼び出すコード:

if (myData){
    QNetworkReply* reply = getMyWobsite(whatever);
    myData->modify(reply);
}

問題ないように見えますが、他のスロットがたまたま呼び出したらどうなるでしょうか

    myData=0;

リクエストの待機中にこのスロットが実行されると、アプリケーションがクラッシュします。関数で QEventLoop を使用する場合は、関数のドキュメントで必ず言及してください。そうすれば、それを使用するプログラマーはこのような問題を回避できます。

他に qt を使用していない場合は、必要なものが既に実装されている代替ライブラリ ( libcurlなど) を検討することもできます。

于 2012-09-02T03:20:43.840 に答える