Qt與QWebEngineView交互完整參考示例代碼
前言
最近剛好需要做一個Qt與Webview的交互,順便寫下整個的交互流程,給需要的各位參考學(xué)習(xí)。后面會補充,Qt上應(yīng)用其他Web上的開源圖標類的組件js庫,例如EChart,vis.js等,通過 Qt+ +JavaScript+ QWebChannel +QWebEngineView 的組合,很多酷炫的效果都可以很方便的做出來。
1:Qt的Web 引擎與 WebView交互歷史變更
Qt 5.6 引入了 Qt WebEngine 模塊:
在過去,Qt 使用的是 Qt WebKit 作為其 Web 引擎。但自 Qt 5.6 版本開始,Qt 引入了基于 Chromium 的新的 Web 引擎,稱為 Qt WebEngine。這個改變帶來了更好的性能、更好的 HTML5 和 CSS3 支持以及更好的安全性。
QWebView 被 QWebEngineView 替代:
在使用 Qt WebKit 時,開發(fā)者使用 QWebView 類來顯示 Web 內(nèi)容。但是隨著 Qt WebEngine 的引入,Qt 引入了 QWebEngineView 類來取代 QWebView。QWebEngineView 基于新的 Web 引擎,并提供了更現(xiàn)代化的 API 和功能。
引入了新的通信機制 - QWebChannel:
在 Qt WebEngine 中,引入了 QWebChannel 作為一種新的機制,用于在 C++ 代碼和 JavaScript 代碼之間進行通信。通過 QWebChannel,可以將 C++ 對象暴露給 JavaScript,使得它們可以相互調(diào)用和交互。
更好的擴展性和性能:
由于 Qt WebEngine 基于 Chromium,因此具有更好的性能和擴展性。它可以使用 Chromium 提供的各種功能和特性,包括先進的渲染引擎、多線程支持、GPU 加速等。
更新的 HTML5 和 CSS3 支持:
Qt WebEngine 提供了更現(xiàn)代化的 HTML5 和 CSS3 支持,使得開發(fā)者可以更輕松地創(chuàng)建豐富、交互性強的 Web 應(yīng)用程序。
這些是 Qt 的 Web 引擎與 WebView 交互方面的一些主要變化??偟膩碚f,隨著 Qt WebEngine 的引入,Qt 在 Web 開發(fā)領(lǐng)域取得了重大進步,為開發(fā)者提供了更好的工具和功能來創(chuàng)建高性能的 Web 應(yīng)用程序。
2:示例展示
示例是完整Qt代碼和Html文件,可以直接測試,注釋也寫了一些
通過QWebChannel進行注冊和調(diào)用:
這種方法是在Qt中注冊QObject對象,使其可以在JavaScript中調(diào)用。使用QWebChannel類來建立Qt與JavaScript之間的通信橋梁。
在Qt代碼中,通過registerObject方法將QObject對象注冊到QWebChannel中,然后在JavaScript中使用該對象??梢远x槽函數(shù)和屬性,這些槽函數(shù)和屬性可以在JavaScript中直接調(diào)用和訪問。在JavaScript中調(diào)用這些槽函數(shù)來執(zhí)行特定的操作,或者讀取和設(shè)置屬性。
這種方法適用于在Web頁面中需要與Qt代碼進行交互的場景,需要從Web頁面中觸發(fā)特定操作,并且在Qt代碼中執(zhí)行相應(yīng)的處理時,或者需要在Web頁面中顯示Qt代碼中的數(shù)據(jù)時這樣做很方便。
如果想要簡單的Qt調(diào)用JavaScript函數(shù)的話,就使用runJavaScript方法就行
總的來說,如果需要頻繁地進行 C++ 和 JavaScript 之間的通信,使用連接信號與槽會更加方便和高效。而如果只是偶爾需要執(zhí)行一些 JavaScript 代碼,使用 `runJavaScript` 也是一個不錯的選擇。
#pragma once #include <QWidget> #include <QJsonObject> class QWebEngineView; class QWebChannel; class frmgplot : public QWidget { Q_OBJECT /*Q_PROPERTY 定義了一個名為 jsonData 的屬性, 其類型為 QJsonObject,并將其與一個名為 qtjsonData 的成員變量關(guān)聯(lián)起來。 當qtjsonData改變時,會自動觸發(fā)qtdataChanged信號 要在類中聲明好 信號(qtdataChanged) 和 成員(qtjsonData) */ Q_PROPERTY(QJsonObject jsonData MEMBER qtjsonData NOTIFY qtdataChanged) public: frmgplot(QWidget *parent); ~frmgplot(); void initfrm(); void setQtjsonData(const QJsonObject & jsonData); public slots: //js 調(diào)用qt函數(shù),注意類型必須要是public slots: void jscallQt(const QString &str); private slots: void onPageLoadFinished(bool success); signals: //當qtjsonData改變時,會自動觸發(fā)qtdataChanged信號 void qtdataChanged(const QJsonObject &jsonData); private: QWebEngineView *m_webView; QWebChannel *m_webChannel; QJsonObject qtjsonData; };
#include "frmgplot.h" #include <QWebEngineView> #include <QWebChannel> #include <QFileInfo> #include <QDir> #include <QApplication> #include <QVBoxLayout> #include <qmessagebox.h> #include <QTimer> frmgplot::frmgplot(QWidget *parent) : QWidget(parent) { //拿到示例后,別忘了在合適的時候 初始化initfrm } frmgplot::~frmgplot() { } void frmgplot::initfrm() { QVBoxLayout *layout = new QVBoxLayout(this); setLayout(layout); // 創(chuàng)建 Web 視圖 m_webView = new QWebEngineView(this); layout->addWidget(m_webView); // 創(chuàng)建 Web 通道 m_webChannel = new QWebChannel(this); // 注冊到 Web 頁面,使 JavaScript 能夠調(diào)用 Qt類里面的 槽函數(shù) m_webChannel->registerObject("frmplot", this); m_webView->page()->setWebChannel(m_webChannel);//設(shè)備交互通道 // 加載 HTML 頁面 QString filePath = QFileInfo(QApplication::applicationDirPath() + "/web/gplot/js/index.html").absoluteFilePath(); m_webView->load(QUrl::fromLocalFile(filePath)); // 連接信號槽以在通道初始化后調(diào)用 JavaScript 函數(shù) connect(m_webView, &QWebEngineView::loadFinished, this, &frmgplot::onPageLoadFinished); } void frmgplot::onPageLoadFinished(bool success) { if (success) { // 頁面加載完成后調(diào)用 JavaScript 函數(shù) // 創(chuàng)建定時器,延遲3秒后執(zhí)行 QTimer::singleShot(3000, this, [=]() { // 頁面加載完成后調(diào)用 JavaScript 函數(shù) m_webView->page()->runJavaScript(QString("qtcalljsfunc('%1');").arg("qt call to js")); }); } } void frmgplot::jscallQt(const QString &str) { QMessageBox::warning(this, QString::fromLocal8Bit("title"), str); /*示例: js 調(diào)用 qt 后, qt再次設(shè)置 屬性jsonData 的qtjsonData成員, 讓其改變 然后 觸發(fā)信號qtdataChanged,從而讓web 捕捉到qtdataChanged信號*/ QJsonObject json; json["obj1"] = 1; json["obj2"] = 666.666; json["obj3"] = "this objstr"; this->setProperty("jsonData", json); setQtjsonData(json); } void frmgplot::setQtjsonData(const QJsonObject &jsonData) { //if (qtjsonData != jsonData) { qtjsonData = jsonData;//會自動觸發(fā)qtdataChanged } }
<!doctype html> <html> <head> <title>Network</title> <script src="qwebchannel.js"></script> <style type="text/css"> #mynetwork { width: 80vw; /* 設(shè)置為全屏寬度的 80% */ height: 80vh; /* 設(shè)置為全屏高度的 80% */ border: 1px solid lightgray; } /* 設(shè)置 body 和 html 的寬度和高度為100%,以使 #mynetwork 占據(jù)整個屏幕 */ body, html { width: 100%; height: 100%; margin: 0; padding: 0; } </style> </head> <body> <button id="jscallqtbutton">js call qt</button> /*定義一個按鈕*/ <p> </p> <div id="mynetwork"></div> <script type="text/javascript"> //----------- webchannel qt js 交互 var updatejson=function(text){ // 使用JSON.stringify將QJsonObject轉(zhuǎn)換為字符串,然后再輸出 alert(JSON.stringify(text)); } var webObject; // Connect to the QWebChannel new QWebChannel(qt.webChannelTransport, function(channel) { webObject = channel.objects.frmplot; window.foo = webObject;//對象賦值給了全局對象 window 的屬性 foo //qt信號{qtdataChanged}與js函數(shù)連接,就像 qt的信號槽一樣 webObject.qtdataChanged.connect(updatejson); // 1: web view -> qt :web上按鈕(jscallqtbutton)按下后,調(diào)用qt函數(shù)jscallQt document.getElementById("jscallqtbutton").onclick = function() { webObject.jscallQt("jscall-qt"); alert("jscallQt"); }; //2:qt -> web js // 示例:在頁面上顯示jsonData的內(nèi)容 /* jsonDataDisplay = document.getElementById("jsonDataDisplay"); jsonDataDisplay.innerHTML = JSON.stringify(jsonData);*/ }); //-------- function qtcalljsfunc(text) { alert((text)); } </script> </body> </html>
3:項目注意事項
3.1 :Qt WebEngine locales directory not found at location 錯誤
這個警告是因為 Qt WebEngine 在運行時需要一些 ICU 數(shù)據(jù)文件,這些文件通常位于 Qt 的安裝目錄中。警告消息顯示 Qt WebEngine 在指定的目錄下找不到 ICU 數(shù)據(jù)文件,因此它會嘗試從其他位置加載
在 Qt WebEngine 中,ICU 數(shù)據(jù)文件主要用于處理文字排版、文字渲染、國際化以及本地化等任務(wù)。因此,運行 Qt WebEngine 應(yīng)用程序時,它會嘗試加載這些 ICU 數(shù)據(jù)文件,以確保在不同地區(qū)和語言環(huán)境下能夠正確地顯示和處理文本。
icudtl.dat
是 Qt 框架使用的 ICU(International Components for Unicode)數(shù)據(jù)文件之一。
icudtl.dat
是在Qt的安裝目錄中的,在安裝目錄中搜索并且incudtl.dat和這些pak文件 復(fù)制到 執(zhí)行文件相同層級目錄下就可以了。*.pak
是 Qt WebEngine 中的資源文件,它們包含了用于支持開發(fā)者工具和其他功能所需的資源。注意拷貝時,要區(qū)分 對應(yīng)版本 。
3.2 運行時 崩潰例如:m_webView->page()->setWebChannel(m_webChannel);或者其他地方莫名崩潰
QtWebEngineProcess.exe
是 Qt WebEngine 模塊的一個子進程,用于在 Qt 應(yīng)用程序中執(zhí)行 Web 頁面的渲染和相關(guān)任務(wù)。通常情況下,QtWebEngineProcess.exe
被設(shè)計為與主應(yīng)用程序(.exe 文件)放置在同一目錄下,這是為了便于它與主應(yīng)用程序之間共享資源和進行通信,否則會出現(xiàn)各種莫名崩潰問題
總結(jié)
到此這篇關(guān)于Qt與QWebEngineView交互的文章就介紹到這了,更多相關(guān)Qt與QWebEngineView交互內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
C++指針作為函數(shù)的參數(shù)進行傳遞時需要注意的一些問題
當指針作為函數(shù)的參數(shù)進行傳遞的時候,本質(zhì)上還是進行的“值傳遞”,也就是復(fù)制了一個新的指向該地址的指針變量2013-10-10解析設(shè)計模式中的Prototype原型模式及在C++中的使用
這篇文章主要介紹了設(shè)計模式中的Prototype原型模式及在C++中的使用,需要的朋友可以參考下2016-03-03C語言實現(xiàn)大學(xué)生考勤管理系統(tǒng)
這篇文章主要為大家詳細介紹了C語言實現(xiàn)大學(xué)生考勤管理系統(tǒng),文中示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下2020-12-12C++實現(xiàn)職工工資管理系統(tǒng)課程設(shè)計
這篇文章主要為大家詳細介紹了C++實現(xiàn)職工工資管理系統(tǒng)課程設(shè)計,文中示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下2022-03-03