QWebView setContent在一个单独的线程中

时间:2012-05-03 22:17:11

标签: multithreading qt event-handling qwebview qtembedded

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

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

我正考虑在其他线程中运行setContent调用,这样它就不会阻止事件处理,我可以在必要时取消它。但是,我得到了可怕的"widgets must be created in the GUI thread",我认为没办法轻易解决这个问题。

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

修改

为了澄清一点,我真正感兴趣的是如何能够停止setContent调用和/或处理GUI消息,以便界面保持响应,使用{{传递大量数据1}}。

编辑2

为了进一步澄清,我正在处理长静态内容,即没有JavaScript,只有很多静态HTML,即使在加载更多内容时用户也希望滚动它。主要想法是即使页面没有满载也允许她/他下页。

3 个答案:

答案 0 :(得分:2)

前段时间我遇到了类似的问题。据我所知,只有页面的主要内容是同步的。

事实是GUI核心“绘制”页面,这是耗时的。因此,主要线程被冻结,直到主要内容被完全加载。

就我而言,解决方案很简单:将主要内容作为辅助内容并使用本地文件!!!

那么,我的建议是什么:

1)准备一个包含以下内容的本地文件(/tmp/loader.html):

<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)只要您需要取消加载,您就可以加载其他内容,删除内容文件或其他可能的方法。

请注意,据我所知,你永远不会异步内容的绘画。这是嵌入式系统中的真正问题。

答案 1 :(得分:1)

由于QWebView::setContent()是阻止通话,我最终使用了解决方案。主要思想是XML处理比呈现页面快得多。因此,我会做以下事情:

  1. 将文档解析为XML DOM文档(在我的情况下是一个合理的假设),并找到body元素。
  2. 仅保留预定义数量的body子元素(类似于20个元素)。将其余元素存储在另一个XML DOM文档中。
  3. 使用QWebView::setContent()显示初始文档(序列化XML),这相对较快。在SLOT(loadNextChunk())上启动超时为0的计时器。
  4. loadNextChunk()使用body->appendInside(html)从正文末尾的备份文档移动另外20个元素,其中bodyQWebElement
  5. 当没有更多元素可用时停止。
  6. 这是有效的,因为在调用loadNextChunk()之间,GUI有机会对事件做出反应。

答案 2 :(得分:0)

顾名思义,QWebView是一个小部件。另一方面,QWebPage是一个普通的旧QObject,具有您可能想要的所有线程优点。

现在把它绑在一起:

void QWebView::setPage ( QWebPage * page )