Qt與Web混合開發(一)


Qt與Web混合開發(一)

來源 https://jaredtao.github.io/2020/03/04/Qt%E4%B8%8EWeb%E6%B7%B7%E5%90%88%E5%BC%80%E5%8F%91(%E4%B8%80)

 

前言

2020年是一個新的開始,希望疫情盡快過去,早日摘下口罩。加油!

簡介

本文是《Qt與Web混合開發》系列文章的第一篇,主要討論Qt與Web混合開發相關技術。

這類技術存在適用場景,例如:Qt項目使用Web大量現成的組件/方案做功能擴展,

Qt項目中性能無關/頻繁更新迭代的頁面用html單獨實現,Qt項目提供Web形式的SDK給

用戶做二次開發等等,或者是Web開發人員齊全而Qt/C++人手不足,諸如此類非技術問題,

都可以使用Qt + Web混合開發。

(不適用的請忽略本文)

(本文內容參考部分官方英文文檔,並加入適當的個人理解和經驗之談,請知悉)

第一篇文章,會先整體介紹一下WebEngine,再提供簡單的Demo,並做一些簡要的說明。

Qt的Web方案

Qt提供的Web方案主要包括 WebEngine/WebView、Quick WebGL Stream、QtWebAssembly三種。

Quick WebGL Stream

可以參考Qt官方的WebGL Stream介紹文檔

https://resources.qt.io/cn/qt-quick-webgl-release-512

resources.qt.io
WebGL Stream在5.12中正式發布,其本質是一種通信技術,將已有的QtQuick程序中渲染指令和數據,通過socket傳輸給Web端,由WebGL實現界面渲染。

其使用方式非常的簡單,無需修改源碼,應用程序啟動時,帶上端口參數,例如:

./your-qt-application -platform webgl:port=8998
(相當於應用程序變成了一個服務器端程序)

這樣程序就在后端運行,看不到界面了,之后瀏覽器打開本地網址 localhost:8998 或者內網地址/映射后的公網地址,就能在瀏覽器中看到程序頁面。

WebGL Stream的應用不多,Qt官方給的案例是:歐洲某工廠的大量傳感器監測設備,都以WebGL Stream的方式運行Qt 程序,本身都不帶顯卡和顯示器,而在控制中心的顯卡/顯示器上,通過Web打開網頁的方式,查看每個設備的運行狀況。因此節約了大量顯卡/顯示器的成本。類比於網吧的無硬盤系統。

濤哥相信,未來結合5G技術會有不錯的應用場景。

Qt WebAssembly

Qt WebAssembly技術,在5.13中正式發布。本質是把Qt程序編譯成瀏覽器支持的二進制文件,由瀏覽器加載運行。

一方面可以將現有的Qt程序編譯成Web,另一方面可以用Qt/C++來彌補Web程序的性能短板。

Qt WebAssembly在使用細節上還有一些坑的地方,需要踩一踩。后續我再寫文章吧。

Qt WebEngine/WebView

Qt提供了WebEngine模塊以支持Web功能。

Qt WebEngine基於google的開源瀏覽器chromium實現,類似的項目還有cefminiblink等等。

QtWebEngine可以看作是一個完整的chromium瀏覽器。

(WebView是同類的方案,稍微有些區別。后文再說。)

QtWebEngine的更新情況

瀏覽器技術十分的龐大,這里先不深入展開,先來關注一下Qt WebEngine對chromium的跟進情況。

數據來源於Qt wiki,Qt每個版本的change log

Qt版本 chromium后端 chromium安全更新
5.9.0 56  
5.9.1 - 59.0.3071.104
5.9.2 - 61.0.3163.79
5.9.3 - 62.0.3202.89
5.9.4 - 63.0.3239.132
5.9.5 - 65.0.3325.146
5.9.6 - 66.0.3359.170
5.9.7 - 69.0.3497.113
5.9.8 - 72.0.3626.121
5.9.9 - 78.0.3904.108
5.12.0 69  
5.12.1   71.0.3578.94
5.12.2   72.0.3626.121
5.12.3   73.0.3683.75
5.12.4   74.0.3729.157
5.12.5   76.0.3809.87
5.12.6   77.0.3865.120
5.12.7   79.0.3945.130
5.14.0 77  
5.14.1   79.0.3945.117

可以看到Qt在WebEngine模塊,一直持續跟進Chromium的更新。

當前(2020/3/4)最新的chromium版本是80。

WebEngine的架構

QtWebEngine提供了C++和Qml的接口,可以在Widget/Qml中渲染HTML、XHTML、SVG,

也支持CSS樣式表和JavaScript腳本。

QtWebEngine的架構圖如下

基於Chromium封裝了一個WebEngineCore模塊,在此之上,

WebEngine Widgets模塊專門用於Widget項目,

WebEngine 模塊用於Qml項目,

WebEngineProcess則是一個單獨的進程,用來渲染頁面、運行js腳本。

Web在單獨的進程里,我們開發的時候知道這一點就好了,不需要額外關注,

只要在發布的時候,帶上QTDIR目錄下的可執行程序QtWebEngineProcess即可。

(這里提一下底層實現原理,使用了進程間共享OpenGL上下文的方式, 實現多個進程的UI混合在一起)

WebEngine的平台要求

(以Qt5.12為參考)

首先一條是:不支持靜態編譯 (因為依賴的chromium、chromium本身的依賴庫 不能靜態編譯)

接下來再看看各平台的要求和限制:

Windows

編譯器要 Visual Studio 2017 version 15.8 以上

系統環境要 Windows 10 SDK

默認只支持X64版本,如果要x86版本,要自己編譯qt源碼。

MacOS

  • MacOS 10.12以上

  • XCode 8.3.3以上

  • MacOS 10.12以上 SDK

不支持32-bit

不兼容 Mac App Store (chromium使用了私有api,App Sandbox和chromium Sandbox優先級問題)

Linux

編譯器要 clang, 或者 gcc 5以上

需要pkg-config來探測依賴庫,dbus-1和 fontconfig是必須的。

如果配置了xcb,還要額外配置相關庫。

WebView

Qt還提供了一個WebView組件,可以用來將Web內容嵌入到Qml程序中。(這個沒有提供Widget的接口)

WebView組件的實現,使用了平台原生api,在移動端意義重大,特別是在ios平台,使用

原生的web view,這樣就能兼容App Store了。

在Windows/MacOS/Linux平台,則是渲染部分還是使用了WebEngine。

WebView的使用可以參考官方例子Minibrowser

WebEngine的使用

WebEngine Widget最簡Demo

源代碼

這里示例一個最簡單的demo, 使用WebEngine Widget模塊提供的QWebEngineView:

1
2
3
4
5
6
7
//Demo.pro
QT += core gui webenginewidgets

CONFIG += c++11

SOURCES += \
main.cpp

注意pro文件中包含的Qt模塊

1
2
3
4
5
6
7
8
9
10
11
12
13
//main.cpp
#include <QApplication>
#include <QWebEngineView>
int main(int argc, char **argv)
{
QApplication app(argc, argv);

QWebEngineView view;
view.load(QUrl("https://www.zhihu.com/"));
view.show();

return app.exec();
}

運行結果

上面代碼以打開知乎首頁為例,運行結果如下

最小發布包

濤哥嘗試了在Windows平台,做出可用的最小發布包:

尺寸在170M左右。這些依賴項中,除了常見的Qt必備項platforms、Qt5Core、Qt5Gui等,

Qt5WebEngineCore是最大的一個,有70M。QtWebEngineProcess.exe是新增加的一個exe程序,

前文說架構圖時提到的單獨進程就是這個程序實現。

resources/icudtl.dat在其它瀏覽器引擎中也常看到。

translations/qtwebengine_locales是WebEngine的翻譯項,不帶可能會發生翻譯問題。

Qt5Positioning、Qt5PrintSupport一般不怎么用,但是不帶這兩個程序起不來。

同時發現Qml和Quick模塊也是必須的,Qt5QuickWidgets也用上了。

濤哥查看源碼后發現WebEngineCore模塊依賴Quick和Qml模塊。

WebEngine Qml最簡Demo

再做一個純Qml的Demo

源碼

pro中增加webengine模塊即可

1
2
3
4
5
6
7
8
9
10
//WebQml.pro
QT += core gui quick qml webengine

CONFIG += c++11

SOURCES += \
main.cpp

RESOURCES += \
Qrc.qrc

注意初始化。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
//main.cpp
#include <QGuiApplication>
#include <QQuickView>
#include <QtWebEngine>
int main(int argc, char *argv[])
{
QCoreApplication::setAttribute(Qt::AA_EnableHighDpiScaling);

QGuiApplication a(argc, argv);
//初始化。時機在QApp之后,Window/View構造之前。
QtWebEngine::initialize();

QQuickView view;
view.setSource(QUrl("qrc:/main.qml"));
view.show();
return a.exec();
}

qml導入模塊,填入url

1
2
3
4
5
6
7
8
9
10
11
//main.qml
import QtQuick 2.0
import QtWebEngine 1.8
Item {
width: 800
height: 600
WebEngineView {
anchors.fill: parent
url: "https://www.zhihu.com"
}
}

運行結果

運行結果和上一個Demo一樣

最小發布包

這回可以去掉Widget模塊

同時也去掉不必要的翻譯文件。包大小160M左右,和前面的差別不大。

下期預告

這回先寫到這里,下次的主題是WebChannel與WebSocket。敬請期待。

 

========== End

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM