很遺憾,QtWebkits在Qt5.6以上版本被淘汰了,對於這個接口良且和其餘類例如QWebFrame完美結合的組件就這麼沒了,我只能表示可惜。對於QtWebEngine新的組件,不得不認可它從Chromium繼承過來的強大的性能,但接口上還不是很豐富,和其餘類的交互也不是很完美,期待Qt可以對其進行進一步開發,我也會不斷的升級Qt,嘗試新的接口。javascript
目前而言,QWebEngine有如下缺點:html
基於咱們的GPS定位項目,參考:[Qt開發北斗定位系統融合百度地圖API及Qt程序打包發佈] ,咱們在該項目中使用的是Qt5.5版本,在嵌入的瀏覽器做爲加載地圖用的是QWebKits組件,咱們將其升級使用QWebEngine進行加載地圖,和HTML和JS進行交互。咱們以此爲例,進行簡要的介紹。java
你剛剛升級到Qt5.6版本可能在UI設計界面時候在組件中找不到QWebEngineView這個組件,沒法從這裏拖拽這個組件到你的UI界面上。我查閱了不少資料,看到別人常用 ui->webEngineview->...
這樣,我甚至懷疑是否由於安裝了其餘版本的Qt影響到了我,我卸載了包含5.6版本的全部Qt,又從新安裝了一遍,可是再重啓軟件後,依然沒有發現QWebEngineView這個鬼東西。在Qt5.5中你也能發現有這樣的組件QWebView,如圖1所示:c++
QWebView組件能夠經過QWebFrame來進行HTML和JS的通訊,若是過渡到QWebEngineView,要是沒有這個UI組件的話,我如何把瀏覽器嵌入到軟件界面,實現網頁和軟件的混合編程呢。根據官方提供的一個例子中,cookiebrowser中找到了答案,這也是官方給的例子中,惟一一個嵌入到網頁中的!(不得不說,Qt給的例子很模糊不好!) 通過研究, QWebEngineView使用widget組件,拖拉出來是一個透明的組件,對着組件按右鍵->promote to.. ->選擇QWebEngineView,如圖2,完成操做。程序員
有了QWebEngineView這個UI組件,咱們能夠在程序中調用其成員、方法和函數完成操做了。web
在使用方法上有很大的區別,能夠說是兩個徹底不一樣理念的東西,這裏爲了更通俗易懂,就不粘貼API文檔中函數解釋,就用最經常使用的!編程
#include <QtWebEngineWidgets> // 基本組件 #include <QWebEnginePage> // HTML頁面 #include <QWebChannel> // C++和JS/HTML雙向通訊,代替了已淘汰的QtWebFrame的功能
在咱們的項目中一開始就要引入這樣的組件,但在咱們的項目中,沒有頻繁用到與JS的互相交互,因此這裏暫時沒有關於QWebChannel的使用方法,只留下這個接口。瀏覽器
如下爲區別:cookie
QUrl url(strMapPath); // strMapPath爲QString類,是你html文件的路徑 ui->webView->load(url); ui->webView->setContentsMargins(0,0,0,0); ui->webView->setTextSizeMultiplier(1);//設置網頁字體大小 connect(ui->webView->page()->mainFrame(), SIGNAL(javaScriptWindowObjectCleared()), this, SLOT(slotPopulateJavaScriptWindowObject()));
咱們會使用load方法加載html所在的界面,使用QWebFrame類的mainFrame()中的SIGNAL和槽函數函數
void Widget::slotPopulateJavaScriptWindowObject() { ui->webView->page()->mainFrame()->addToJavaScriptWindowObject("ReinforcePC", this); }
進行響應。參考文獻1:《javascript調用qt》,能夠解釋這個槽函數的重要性。
QWebEnginePage *page = new QWebEnginePage(this); // 定義一個page做爲頁面管理 QWebChannel *channel = new QWebChannel(this); // 定義一個channel做爲和JS或HTML交互 page->load(strMapPath); // page上加載html路徑 page->setWebChannel(channel); // 把channel配置到page上,讓channel做爲其信使 ui->webEngine->setPage(page); // 創建page和UI上的webEngine的聯繫
若是你的 初始化程序寫到這裏,當你運行程序的時候,不管是webKits裏的WebView仍是新版的webEngineView,你的UI界面上的那個組件區域就會顯示那個html文件了。
到此,咱們完成了二者的初始化。
咱們以按鈕的槽函數爲例,當點擊按鈕時,會向JS發送命令,運行JS腳本,咱們這裏發送的是將顯示變爲衛星圖的JS命令:
void Widget::on_pushButtonStreetMap_clicked() { QWebFrame *frame = ui->webView->page()->mainFrame(); // 定義一個QWebFrame負責交互 QString cmd = QString("showStreetMap()"); // JS的命令 frame->evaluateJavaScript(cmd); // 使用frame下的命令運行該命令 }
從這個例子中咱們也能夠看到,QWebFrame是JS交互的關鍵。
仍是以該槽函數爲例:
void Widget::on_pushButtonSatelliteMap_clicked() { QString cmd = "showSatelliteMap()"; ui->webEngine->page()->runJavaScript(cmd); // 直接page()下就能夠運行 }
在JS單向通訊中十分簡單,也不須要使用QWebChannel信使,但該方法runJavaScript()沒法在構造函數中使用,緣由不明。也能夠這樣使用:
connect(ui->webEngine,&QWebEngineView::loadFinished,[=](int){ ui->webEngine->page()->runJavaScript(cmd1);
第二個參數SIGNAL位置的,只能使用這樣的方式調用,若是使用SIGNAL(....loadFinished),報錯。
經過這樣的方法,咱們就完成了一個初級的過渡。本人因爲是研究嵌入式的程序員,只是上位機學習簡單的Qt作一點點當成輔助開發,並無什麼高深的Qt技術,也正在學習中,歡迎討論。
[1] 在水一方著.javascript調用Qt.CSDN博客.2011-07-18.
[2]Я!ńɡ著.QT5利用chromium內核與HTML頁面交互.CNBLOGS. 2015-11-17.
[3]liuyez123著.[實現QT與HTML頁面通訊]. CSDN博客. 2016-01-13.