2

QWebView::setContent()一部のHTMLコンテンツをQWebViewにロードするために使用する必要があるアプリケーションがあります。これはすべて、ARMv5プロセッサ(400 MHzと考えてください)を搭載した組み込みデバイスで発生します。ほとんどの場合、妥当な時間(最大5秒)でページをロードできますが、ロードに時間がかかるコンテンツ(300KBのコンテンツの場合は最大30秒)がある場合があります。

問題は、setContent呼び出しがメインスレッドをブロックすることです。ロード中にイベントを処理できるようにする必要があります。ユーザーがこれ以上待たないことを決定した場合は、ロードをキャンセルすることもできます。

setContentイベント処理をブロックせず、必要に応じてキャンセルできるように、他のスレッドで呼び出しを実行することを考えていました。しかし、 「ウィジェットはGUIスレッドで作成する必要がある」という恐ろしいものがあり、これを簡単に解決する方法がわかりません。

QWebView::setContent別のスレッドで実行することは可能ですか?もしそうなら、どのように?そうでない場合、実行中にGUIイベントを処理することは可能setContentですか?setContent通話を「キャンセル」することはできますか?

編集

もう少し明確にするために、私が本当に興味を持っているのは、setContent呼び出しを停止したり、GUIメッセージを処理したりして、インターフェースが応答性を維持し、を使用して大量のデータが渡されるようにする方法setContentです。

編集2

さらに明確にするために、私は長くて静的なコンテンツを扱っています。つまり、JavaScriptはなく、静的なHTMLがたくさんあり、ユーザーがより多くのコンテンツをロードしている間でもスクロールしたいと思っています。主なアイデアは、ページが完全にロードされていない場合でも、彼女/彼がページを下に移動できるようにすることです。

4

3 に答える 3

3

しばらく前、私は同様の問題に直面しました。私の知る限り、ページのメインコンテンツのみが同期して動作しています。

事実、GUIコアはページを「ペイント」し、これには時間がかかります。そのため、メインコンテンツが完全にロードされるまで、メインスレッドはフリーズします。

私の場合、解決策は単純でした。メインコンテンツをセカンダリコンテンツにして、ローカルファイルを操作する!!!

だから、私の提案は何ですか:

/tmp/loader.html1)次のようなものを含むローカルファイル()を準備します。

<html>
<body onload='setTimeout(function() { window.location="contents.html"; }, 1000);'>
Loading...
</body>
</html>

2)新しいコンテンツをロードする必要があるたびに、それをセカンダリファイル( )に保存/tmp/contents.htmlし、ローダーの更新を強制します(おそらく更新も)。簡単:

QFile f("/tmp/contents.html");
if (f.open(QFile::WriteOnly)) {
    qint64 pos = 0;
    while (pos < contents.length()) {
        pos += f.write(contents.mid(pos, 1024)); // chunk of 1024
        qApp->processEvents();
    }
    f.close();
    webview->setUrl(QUrl::fromLocalFile("/tmp/loader.html"));
}

ファイルの保存も遅い場合は、イベントループが保留中のイベントを処理することを許可していることに注意してください...

3)ロードをキャンセルする必要があるときはいつでも、別のコンテンツをロードしたり、コンテンツファイルを削除したり、その他の可能な方法を実行したりできます。

私の知る限り、コンテンツのペイントを非同期にすることは決してないことに注意してください。そして、それが組み込みシステムの本当の問題です。

于 2012-05-09T16:15:54.630 に答える
2

はブロッキング呼び出しであるためQWebView::setContent()、回避策を使用することになりました。主なアイデアは、XML処理はページのレンダリングよりもはるかに高速であるということです。したがって、私は次のことを行います。

  1. ドキュメントをXMLDOMドキュメント(私の場合は妥当な仮定)として解析し、body要素を見つけます。
  2. の子要素の事前定義された数body(20要素など)のみを保持します。残りの要素を別のXMLDOMドキュメントに保存します。
  3. を使用して初期ドキュメント(シリアル化されたXML)を表示しますQWebView::setContent()。これは比較的高速です。タイムアウト0でタイマーを開始しSLOT(loadNextChunk())ます。
  4. loadNextChunk()を使用して、本文の最後にあるバックアップドキュメントからさらに20個ほどの要素を移動します。body->appendInside(html)ここbodyで、はQWebElementです。
  5. 使用可能な要素がなくなったら停止します。

これが機能するのは、への呼び出しの間にloadNextChunk()、GUIがイベントに反応する機会があるためです。

于 2012-05-12T16:39:50.227 に答える
0

QWebViewは、その名前が示すように、ウィジェットです。一方、 QWebPageは、単純な古いQObjectであり、必要になる可能性のあるすべてのスレッド機能を備えています。

今それを一緒に結びます:

void QWebView::setPage ( QWebPage * page )
于 2012-05-10T01:39:04.610 に答える