2

我有一个应用程序需要用于QWebView::setContent()将一些 HTML 内容加载到 QWebView。所有这些都发生在带有 ARMv5 处理器(想想 400 MHz)的嵌入式设备上。大多数时候,我可以在合理的时间内加载页面(最多 5 秒),但有时我的内容需要很长时间才能加载(300KB 的内容大约需要 30 秒)。

问题是setContent调用阻塞了主线程。我需要能够在加载期间处理事件,如果用户决定不再等待,甚至可以取消加载。

我正在考虑setContent在其他线程中运行调用,以便它不会阻塞事件处理,并且我可以在必要时取消它。但是,我得到了可怕的“必须在 GUI 线程中创建小部件”,而且我认为没有办法轻松解决这个问题。

是否可以QWebView::setContent在单独的线程中运行?如果是这样,怎么做?如果没有,是否可以在setContent运行时处理 GUI 事件?是否可以“取消”setContent通话?

编辑

再澄清一点,我真正感兴趣的是如何能够停止setContent调用和/或处理 GUI 消息,以便界面保持响应,并使用setContent.

编辑 2

为了进一步澄清,我正在处理长的静态内容,即没有 JavaScript,只有大量静态 HTML,即使在加载更多内容时用户也希望通过这些 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. 将文档解析为 XML DOM 文档(在我的例子中是一个合理的假设),然后找到body元素。
  2. 只保留预定义数量的子元素body(大约 20 个元素)。将剩余元素存储在另一个 XML DOM 文档中。
  3. 使用 显示初始文档(序列化 XML)QWebView::setContent(),相对较快。启动一个超时时间为 0 的计时器SLOT(loadNextChunk())
  4. loadNextChunk()使用 . 从正文末尾的备份文档中移动另外 20 个左右的元素body->appendInside(html),其中bodya 是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 回答