WebEngine 内容操作示例
演示如何加载和操作网页内容。
内容操作演示了如何使用 JQuery 和Qt WebEngine Widgets创建一个具有特效和内容操作功能的网页浏览器。
在应用程序中,我们调用QWebEnginePage::runJavaScript() 来执行 jQuery JavaScript 代码。我们将QMainWindow 与QWebEngineView 作为中心部件来构建浏览器本身。
运行示例
要从 Qt Creator,打开Welcome 模式,然后从Examples 中选择示例。更多信息,请参阅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 和读取文件内容来加载 jQuery 库。jQuery 库是一个 JavaScript 库,提供不同的 HTML 操作函数:
QFile文件;file.setFileName(":/jquery.min.js");if(!file.open(QIODevice::ReadOnly)) { qFatal("Failed to read jQuery file %s: %s", qPrintable(file.fileName()), qPrintable(file.errorString())); } jQuery=file.readAll(); jQuery.append("\nvar Qt XML = { '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); }
页面加载时,adjustLocation()
会被QWebEngineView 中的loadFinished()
信号触发,以更新地址栏:
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()
方法。然后,该方法会更新标题栏中的进度,并调用runJavaScript()
,以根据当前网页评估 jQuery 库:
void MainWindow::finishLoading(bool) { progress = 100; adjustTitle(); view->page()->runJavaScript(jQuery); rotateImages(rotateAction->isChecked()); }
这意味着 JavaScript 可被视为加载到QWebEngineView 的内容的一部分,因此每次加载新页面时都需要加载 JavaScript。jQuery库加载完成后,我们就可以开始在浏览器中执行不同的jQuery函数了。
然后明确调用rotateImages()
函数,以确保新加载页面的图像尊重切换操作的状态。
第一个基于 jQuery 的函数是highlightAllLinks()
,用于突出显示当前网页中的所有链接。JavaScript 代码会查找名为a 的网页元素,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()
方法删除所有对象元素:
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); }
© 2025 The Qt Company Ltd. Documentation contributions included herein are the copyrights of their respective owners. The documentation provided herein is licensed under the terms of the GNU Free Documentation License version 1.3 as published by the Free Software Foundation. Qt and respective logos are trademarks of The Qt Company Ltd. in Finland and/or other countries worldwide. All other trademarks are property of their respective owners.