2010-02-05 79 views
10

我正在使用沒有QWebView的QWebPage,因爲我想將HTML文件的內容渲染到QPixmap/QImage上。QtWebkit同步加載

我想要加載的頁面是同步完成的,不是這是默認的異步。默認的方法是調用QWebFrame::setHtml()QWebFrame::setContent(),但這會異步加載圖像。我想要的是某種阻塞函數調用,如QWebFrame::waitUntilLoadFinished()之後,我可以撥打render()並完成它。

我找不到辦法做到這一點。我錯過了什麼嗎?

回答

0

如果有人有興趣,我使用一個特殊的「PageRasterizer」類實現了這一點。

該類在構造函數中創建一個QWebPage,並將bool加載標誌設置爲false。 A connect()呼叫將loadFinished信號連接到僅將加載標誌設置爲真的成員插槽。

一個特殊的RenderPage()返回圖像的成員函數完成所有工作:它接受HTML字符串並調用setHtml()。之後出現一個while循環,在標誌上等待;當標誌爲假時,qApp->processEvents()被調用,所以信號被髮射並且標誌設置槽最終被調用。當它是,循環中斷,現在你可以將頁面渲染到一個QImage(不要忘記在返回之前將標誌設置爲false)。

如果您對渲染過程感興趣,請查看this Qt exampleThumbnailer::render()函數)。

對於獎勵積分,您可以將此課程作爲函數。

+1

我絕對建議不要通過循環使用繁忙的輪詢,而是像等待條件一樣進行適當的同步。 – 2010-02-06 14:26:44

+0

除非Qt事件循環正在運行,否則信號不會被髮射。但事件循環處理事件然後返回。我的解決方案只是運行Qt事件處理,直到Webkit完成加載。 我想看看你的代碼使用QWaitConditions _when你沒有訪問Webkit線程_... – Lucas 2010-02-06 15:01:51

+0

我說*推薦*,當然我假設你沒有使用主線程作爲工作線程,這意味着你根本不需要手動輪詢事件。 – 2010-02-07 21:05:18

2

該方法存在的問題是,您基本上需要等待不確定的時間,並且如果您從主線程發出呼叫,則會阻止事件處理,因此信號如loadFinished

雖然你可以得到解決,通過顯式泵送事件,我不認爲這會阻止您發佈頁面加載一個固有的問題,只是做加工時loadFinished發生。
如果您需要輔助線程來等待頁面,則可以始終讓這些線程使用同步機制進行等待。

+0

等待不是問題,資源來自磁盤,我控制它們。他們非常小。但是你給了我一個關於QFutureWatcher的想法...... – Lucas 2010-02-05 15:23:02

+0

另外,我明確地希望避免等待信號。我只想從磁盤加載一個小頁面,將其渲染爲圖像並返回該圖像。這應該是一個功能,而不是幾個+插槽+等待信號等等。 – Lucas 2010-02-05 15:25:55

+0

由於Qt本身沒有提供,所以你必須等待信號 - 即使它只是被某些代碼隱藏。我還沒有試過Qts未來的觀察者,但是這個例子看起來像它可以做到你想要的 - 等待信號。 – 2010-02-05 15:48:48

7

我建議你這樣做的Qt方式,並做到異步,它幫助很多

如果您仍想在同步中執行此操作,請在單獨的QThread中使用QEventLoop

查看我的評論,瞭解詳細的QThread使用信息。注意:不要忘記調用moveToThread();在線程頭文件中,或者所有的信號將通過QApplication執行循環。

+0

現在看_that's_有用的信息。我不知道QEventLoop。現在我可以將它推到一個新線程並等待完成。 – Lucas 2010-02-08 23:38:30

+0

相當悲傷我仍然得到了「解決」,也沒有upvote:P – drahnr 2010-02-09 08:16:13

+2

正確的QThread用法見http://labs.qt.nokia.com/2010/06/17/youre-doing-it-wrong/ – drahnr 2011-05-22 19:24:07

7

如果有人仍然需要它,這是我如何得到它的工作。

mWebPage->mainFrame()->setHtml("..."); 
QEventLoop loop; 
connect(mWebPage,SIGNAL(loadFinished(bool)),&loop,SLOT(quit())); 
loop.exec(); 
/* your webpage has finished loading & is ready to use */ 
+0

OMG。這樣可行!非常感謝。 – 2014-12-31 16:00:42

+1

爲了更加安全,您可以添加一個帶有超時的單次計時器,以在出現錯誤時退出事件循環:QTimer.singleShot(10000,loop.quit) – 2016-05-23 18:17:02