WebEngine内容操作示例
演示如何加载和操作网页内容。
内容操作展示了如何使用JQuery结合Qt WebEngine Widgets创建带特殊效果和内容操作的网页浏览器。
在应用程序中,我们调用QWebEnginePage::runJavaScript()来执行jQuery JavaScript代码。我们实现一个包含QWebEngineView的QMainWindow作为主控件来构建浏览器本身。
运行示例
要从Qt Creator运行示例,打开欢迎模式并从示例中选择示例。有关更多信息,请访问构建和运行示例。
MainWindow类定义
MainWindow
类继承自QMainWindow。它实现了一系列槽以在应用程序和网页内容上执行操作
class MainWindow : public QMainWindow { Q_OBJECT public: MainWindow(const QUrl& url); protected slots: void adjustLocation(); void changeLocation(); void adjustTitle(); void setProgress(int p); void finishLoading(bool); void viewSource(); void highlightAllLinks(); void rotateImages(bool invert); void removeGifImages(); void removeInlineFrames(); void removeObjectElements(); void removeEmbeddedElements(); private: QString jQuery; QWebEngineView *view; QLineEdit *locationEdit; QAction *rotateAction; int progress; };
我们还声明了一个包含jQuery的QString,一个显示网页内容的QWebEngineView,以及一个作为地址栏的QLineEdit。
MainWindow类实现
我们首先实现构造函数。构造函数的第一部分将progress
的值设置为0。这个值将在代码中稍后用于可视化加载网页
接下来,通过QFile
读取文件内容使用QFile加载jQuery库。jQuery库是一个提供用于操作HTML的不同功能的JavaScript库。
QFile file; file.setFileName(":/jquery.min.js"); file.open(QIODevice::ReadOnly); jQuery = file.readAll(); jQuery.append("\nvar qt = { 'jQuery': jQuery.noConflict(true) };"); file.close();
构建函数的第二部分创建一个QWebEngineView并将槽连接到视图的信号
view = new QWebEngineView(this); view->load(url); connect(view, &QWebEngineView::loadFinished, this, &MainWindow::adjustLocation); connect(view, &QWebEngineView::titleChanged, this, &MainWindow::adjustTitle); connect(view, &QWebEngineView::loadProgress, this, &MainWindow::setProgress); connect(view, &QWebEngineView::loadFinished, this, &MainWindow::finishLoading);
此外,我们创建一个作为浏览器地址栏的QLineEdit。然后我们将垂直QSizePolicy设置为始终填充浏览器中的可用区域。我们将QLineEdit添加到一个包含来自QWebEngineView::pageAction()的导航操作的QToolBar
locationEdit = new QLineEdit(this); locationEdit->setSizePolicy(QSizePolicy::Expanding, locationEdit->sizePolicy().verticalPolicy()); connect(locationEdit, &QLineEdit::returnPressed, this, &MainWindow::changeLocation); QToolBar *toolBar = addToolBar(tr("Navigation")); toolBar->addAction(view->pageAction(QWebEnginePage::Back)); toolBar->addAction(view->pageAction(QWebEnginePage::Forward)); toolBar->addAction(view->pageAction(QWebEnginePage::Reload)); toolBar->addAction(view->pageAction(QWebEnginePage::Stop)); toolBar->addWidget(locationEdit);
构建函数的第三部分实现了两个QMenu小部件并将一系列操作分配给它们
QMenu *viewMenu = menuBar()->addMenu(tr("&View")); QAction *viewSourceAction = new QAction(tr("Page Source"), this); connect(viewSourceAction, &QAction::triggered, this, &MainWindow::viewSource); viewMenu->addAction(viewSourceAction); QMenu *effectMenu = menuBar()->addMenu(tr("&Effect")); effectMenu->addAction(tr("Highlight all links"), this, &MainWindow::highlightAllLinks); rotateAction = new QAction(this); rotateAction->setIcon(style()->standardIcon(QStyle::SP_FileDialogDetailedView)); rotateAction->setCheckable(true); rotateAction->setText(tr("Turn images upside down")); connect(rotateAction, &QAction::toggled, this, &MainWindow::rotateImages); effectMenu->addAction(rotateAction); QMenu *toolsMenu = menuBar()->addMenu(tr("&Tools")); toolsMenu->addAction(tr("Remove GIF images"), this, &MainWindow::removeGifImages); toolsMenu->addAction(tr("Remove all inline frames"), this, &MainWindow::removeInlineFrames); toolsMenu->addAction(tr("Remove all object elements"), this, &MainWindow::removeObjectElements); toolsMenu->addAction(tr("Remove all embedded elements"), this, &MainWindow::removeEmbeddedElements);
最后一行将QWebEngineView设置为QMainWindow中的中心小部件
setCentralWidget(view); }
当页面加载时,由QWebEngineView中的loadFinished()
信号触发的adjustLocation()
更新地址栏
void MainWindow::adjustLocation() { locationEdit->setText(view->url().toString()); }
在 changeLocation()
函数中,我们创建了一个 QUrl 对象,然后使用它将页面加载到 QWebEngineView 中。当新的网页完成加载时,adjustLocation()
将再次执行以更新地址栏
void MainWindow::changeLocation() { QUrl url = QUrl::fromUserInput(locationEdit->text()); view->load(url); view->setFocus(); }
adjustTitle()
方法设置窗口标题并显示加载进度
void MainWindow::adjustTitle() { if (progress <= 0 || progress >= 100) setWindowTitle(view->title()); else setWindowTitle(QStringLiteral("%1 (%2%)").arg(view->title()).arg(progress)); } void MainWindow::setProgress(int p) { progress = p; adjustTitle(); }
此槽由 QWebEngineView 中的 titleChanged()
信号触发。
当网页加载完成后,QWebEngineView 中的 loadFinished()
信号会触发 finishLoading()
方法。然后该方法更新标题栏中的进度并在当前网页上评估 jQuery 库
void MainWindow::finishLoading(bool) { progress = 100; adjustTitle(); view->page()->runJavaScript(jQuery); rotateImages(rotateAction->isChecked()); }
这意味着 JavaScript 可以被视为加载到 QWebEngineView 内容的一部分,因此每当加载新页面时都需要加载。一旦加载了 jQuery 库,我们就可以开始执行浏览器中的不同 jQuery 函数。
之后显式调用 rotateImages()
函数,以确保新加载页面的图片符合切换操作的状态。
第一个基于 jQuery 的函数 highlightAllLinks()
设计用来突出显示当前网页中的所有链接。JavaScript 代码查找名为 a 的网络元素,这是超链接的标签。对于每个这样的元素,使用 CSS 设置其背景颜色为黄色
void MainWindow::highlightAllLinks() { QString code = QStringLiteral("qt.jQuery('a').each( function () { qt.jQuery(this).css('background-color', 'yellow') } )"); view->page()->runJavaScript(code); }
rotateImages()
函数旋转当前网页上的图片。此 JavaScript 代码依赖于 CSS 变换。它查找所有 img 元素,旋转图片 180 度然后再旋转回来
void MainWindow::rotateImages(bool invert) { QString code; if (invert) code = QStringLiteral("qt.jQuery('img').each( function () { qt.jQuery(this).css('transition', 'transform 2s'); qt.jQuery(this).css('transform', 'rotate(180deg)') } )"); else code = QStringLiteral("qt.jQuery('img').each( function () { qt.jQuery(this).css('transition', 'transform 2s'); qt.jQuery(this).css('transform', 'rotate(0deg)') } )"); view->page()->runJavaScript(code); }
剩余的方法从当前网页中删除不同的元素。removeGifImages()
通过查找网页上所有元素的 src 属性来删除网页上的所有 GIF 图片。任何具有 gif 文件作为其源文件的元素都被删除
void MainWindow::removeGifImages() { QString code = QStringLiteral("qt.jQuery('[src*=gif]').remove()"); view->page()->runJavaScript(code); }
removeInlineFrames()
方法删除所有的 iframe 或内联元素
void MainWindow::removeInlineFrames() { QString code = QStringLiteral("qt.jQuery('iframe').remove()"); view->page()->runJavaScript(code); }
removeObjectElements()
方法删除所有的 object 元素
void MainWindow::removeObjectElements() { QString code = QStringLiteral("qt.jQuery('object').remove()"); view->page()->runJavaScript(code); }
removeEmbeddedElements()
方法删除使用 embed 标签的任何元素,例如网页上嵌入的插件
void MainWindow::removeEmbeddedElements() { QString code = QStringLiteral("qt.jQuery('embed').remove()"); view->page()->runJavaScript(code); }
© 2024 The Qt Company Ltd. 本文件所包含的文档贡献的版权归其所有者所有。本文件提供的文档受 GNU 自由文档许可证版本 1.3 的许可,该许可证由自由软件基金会发布。Qt 和相应徽标是 The Qt Company Ltd. 在芬兰和/或世界上其他国家的商标。所有其他商标均为其所有者的财产。