一、Qt WebEngine基本概念
????????Qt WebEngine中主要分為三個模塊:Qt WebEngine Widgets模塊,主要用于創建基于C++ Widgets部件的Web程序;Qt WebEngine模塊用來創建基于Qt Quick的Web程序;Qt WebEngine Core模塊用來與Chromeium交互。網頁玄幻和JavaScript的執行從GUI進程分離到Qt WebEngine進程,主要架構如下。
二、Qt WebEngine Widgets
本文主要關注Qt WebEngine Widgets模塊,其架構如下。QWebEngineView是主要窗體類組件,用來加載Web。QWebEnginePage包含在QWebEngineView中,主要包含了Web頁面的主框架,負責內容分、瀏覽歷史QWebEngineHistory等。配置QWebEngineProfile用于區分不同的Page,屬于同一個Web引擎配置的所有網頁共享設置Settings、腳本Script和Cookies。
三、一個簡易的瀏覽器
????????重寫QWebenginePage的acceptNavigationRequest進行導航設置,沒有特殊需求可只用用基類。
class CustomWebEnginePage : public QWebEnginePage {Q_OBJECT
public:CustomWebEnginePage(QObject *parent = nullptr) : QWebEnginePage(parent) {}bool acceptNavigationRequest(const QUrl &url, NavigationType type, bool isMainFrame) override {if (type == QWebEnginePage::NavigationTypeLinkClicked && isMainFrame) {load(url); // 允許在當前頁面打開新鏈接return false; // 阻止默認打開新窗口的行為}return QWebEnginePage::acceptNavigationRequest(url, type, isMainFrame);}
};
?瀏覽器頁面實現細節:
void Test2015::TestWebEngineWidget()
{if (ui.frameWeb){auto& pParent = ui.webEngineView;auto& pWebView = ui.webEngineView;//pWebView->setPage(new CustomWebEnginePage(pWebView));pWebView->load(QUrl("https://blog.csdn.net/WSTONECH?type=blog"));QWebEngineSettings::globalSettings()->setAttribute(QWebEngineSettings::JavascriptEnabled, true);pWebView->settings()->setAttribute(QWebEngineSettings::JavascriptEnabled, true);pWebView->settings()->setAttribute(QWebEngineSettings::LinksIncludedInFocusChain, true);//工具欄urlEdit = new QLineEdit(pParent);backButton = new QPushButton("Back", pParent);forwardButton = new QPushButton("Forward", pParent);refreshButton = new QPushButton("Refresh", pParent);goButton = new QPushButton("Go", pParent);favBtn = new QPushButton("收藏", pParent);QHBoxLayout *toolbarLayout = new QHBoxLayout(ui.frameToolBar);toolbarLayout->addWidget(backButton);toolbarLayout->addWidget(forwardButton);toolbarLayout->addWidget(refreshButton);toolbarLayout->addWidget(urlEdit);toolbarLayout->addWidget(goButton);toolbarLayout->addWidget(favBtn);//歷史記錄ListViewhistoryModel = new QStringListModel(pParent);ui.listView_History->setModel(historyModel);//進度條ui.progressBar->setMaximum(100);ui.progressBar->setVisible(false);//connect(urlEdit, &QLineEdit::returnPressed, [=]() {QString urlStr = urlEdit->text().trimmed();QUrl url = urlStr.startsWith("http") ? QUrl(urlStr) : QUrl("https://" + urlStr);if (url.isValid()) {pWebView->setUrl(url);}});connect(pWebView->page(), &QWebEnginePage::urlChanged, urlEdit, [=](QUrl url) {urlEdit->setText(url.toString());});//進度條更新connect(pWebView, &QWebEngineView::loadProgress, this, [=](int progressValue) {if (progressValue == 100) {ui.progressBar->setVisible(false);}else {ui.progressBar->setVisible(true);ui.progressBar->setValue(progressValue);}});//更新歷史地址 頁面加載完成在記錄歷史地址防止未完全加載title等無法解析connect(pWebView, &QWebEngineView::loadFinished, this, [=](bool ok) {if (ok){historyUrls.clear();QList<QWebEngineHistoryItem> items = pWebView->history()->items();for (const QWebEngineHistoryItem& item : items) {if (item.isValid() && (item.url().toString() != "about:blank")){string title = item.title().toStdString();string urlstr = item.url().toString().toStdString();historyUrls.append(item.title() + " - " + item.url().toString());}}historyModel->setStringList(historyUrls);}});//connect(ui.listView_History->selectionModel(), &QItemSelectionModel::currentChanged,this, [=](const QModelIndex& index) {if (!index.isValid()) return;QList<QWebEngineHistoryItem> items = pWebView->history()->items();if (index.row() >= 0 && index.row() < items.size()) {pWebView->load(items[index.row()].url());}});connect(favBtn, &QPushButton::clicked, this, [=]() {QString url = pWebView->url().toString();});connect(backButton, &QPushButton::clicked, this, [=]() {if (pWebView->page()->history()->canGoBack()) {pWebView->back();}});connect(forwardButton, &QPushButton::clicked, this, [=]() {if (pWebView->page()->history()->canGoForward()) {pWebView->forward();}});connect(refreshButton, &QPushButton::clicked, pWebView, &QWebEngineView::reload);connect(goButton, &QPushButton::clicked, this, [=]() {QString input = urlEdit->text();QUrl url;if (input.startsWith("http://") || input.startsWith("https://")) {url = QUrl(input);}else {url = QUrl("https://" + input);}if (url.isValid()) {pWebView->setUrl(url);}});}
}
實現效果?????????????????????????????????????????????????????????????????????????