Qt - QtWebEngineWidgets模块
1、QtWebEngineWidgets模块


.pro文件添加模块
qmake:
QT += webenginewidgets
添加头文件
#include <QtWebEngineWidgets>
#include <QWebEnginePage>
#include <QWebEngineView>
1.1 QWebEnginePage
在windows系统下 QWebEnginePage支持MSVC编译器编译、不支持mingw编译。
QWebEnginePage 是 Qt 的一个类,它用于表示 Web 浏览的页面。它是基于 Chromium 的,并且是 Qt WebEngine 模块的一部分。
QWebEnginePage管理HTML文档的内容、导航链接的历史记录和操作。QWebEnginePage的API与QWebEngineView非常相似,所以我们仍然可以使用常见的函数,例如action()(在QWebEngineView中称为pageAction())、triggerAction()和findText()。
以下是一些使用 QWebEnginePage 的基本示例:
-
创建一个简单的 Web 页面并导航到指定的 URL:
#include "QtWidgetsApplication1.h" #include <QtWebEngineWidgets> #include <QWebEnginePage> #include <QWebEngineView> QtWidgetsApplication1::QtWidgetsApplication1(QWidget *parent) : QWidget(parent) { ui.setupUi(this); QWebEngineView* view = new QWebEngineView(this); view->setFixedSize(this->width(),this->height()); QWebEnginePage* page = new QWebEnginePage(view); view->setPage(page); view->load(QUrl("http://www.example.com")); view->show(); } QtWidgetsApplication1::~QtWidgetsApplication1() { }
运行效果:

-
使用
QWebEnginePage的runJavaScript方法在页面上运行 JavaScript 代码:#include "QtWidgetsApplication1.h" #include <QtWebEngineWidgets> #include <QWebEnginePage> #include <QWebEngineView> QtWidgetsApplication1::QtWidgetsApplication1(QWidget *parent) : QWidget(parent) { ui.setupUi(this); QWebEngineView* view = new QWebEngineView(this); view->setFixedSize(this->width(),this->height()); QWebEnginePage* page = new QWebEnginePage(view); view->setPage(page); view->load(QUrl("http://www.example.com")); view->show(); page->runJavaScript("alert('Hello, world!')"); //page->runJavaScript("document.getElementById('elementId').click();"); } QtWidgetsApplication1::~QtWidgetsApplication1() { }运行结果:

-
使用
QWebEnginePage的setHtml方法加载和显示 HTML 内容:#include "QtWidgetsApplication1.h" #include <QtWebEngineWidgets> #include <QWebEnginePage> #include <QWebEngineView> QtWidgetsApplication1::QtWidgetsApplication1(QWidget *parent) : QWidget(parent) { ui.setupUi(this); QWebEngineView* view = new QWebEngineView(this); view->setFixedSize(this->width(),this->height()); QWebEnginePage* page = new QWebEnginePage(view); view->setPage(page); view->load(QUrl("http://www.example.com")); view->show(); QString html = "<html><head><title>Example</title></head><body><h1>Hello, World!</h1></body></html>"; page->setHtml(html); } QtWidgetsApplication1::~QtWidgetsApplication1() { }
运行结果:

-
使用
QWebEnginePage的profile属性来设置浏览器配置:#include "QtWidgetsApplication1.h" #include <QtWebEngineWidgets> #include <QWebEnginePage> #include <QWebEngineView> #include <QWebEngineProfile> QtWidgetsApplication1::QtWidgetsApplication1(QWidget *parent) : QWidget(parent) { ui.setupUi(this); QWebEngineView* view = new QWebEngineView(this); view->setFixedSize(this->width(),this->height()); QWebEnginePage* page = new QWebEnginePage(view); QWebEngineProfile* profile = new QWebEngineProfile(); //profile->setRequestInterceptor(interceptor); // 设置请求拦截器 profile->setUrlRequestInterceptor(interceptor);// 设置请求拦截器 view->setPage(page); view->load(QUrl("http://www.example.com")); view->show(); QString html = "<html><head><title>Example</title></head><body><h1>Hello, World!</h1></body></html>"; page->setHtml(html); } QtWidgetsApplication1::~QtWidgetsApplication1() { }
5.使用 QWebEnginePage 实现模拟自动点击与输入
#include "QtWidgetsApplication1.h"
#include <QtWebEngineWidgets>
#include <QWebEnginePage>
#include <QWebEngineView>
#include <qpushbutton.h>
QtWidgetsApplication1::QtWidgetsApplication1(QWidget *parent)
: QWidget(parent)
{
ui.setupUi(this);
setFixedSize(950,650);
QPushButton* btn = new QPushButton("Btn");
btn->show();
connect(btn, &QPushButton::clicked ,this, &QtWidgetsApplication1::onClicked);
view = new QWebEngineView(this);
view->setFixedSize(this->width(), this->height());
page = new QWebEnginePage(view);
view->setPage(page);
view->load(QUrl("https://www.baidu.com"));
view->show();
}
QtWidgetsApplication1::~QtWidgetsApplication1()
{
}
void QtWidgetsApplication1::onClicked()
{
//---JavaScript代码-----//
// 获取input元素
//var input = document.getElementById('myInput');
// 设置input的值
//input.value = '手动输入的文本';
// 触发input事件
//var event = new Event('input', { bubbles: true });
//input.dispatchEvent(event);
// 如果需要触发change事件
//var changeEvent = new Event('change', { bubbles: true });
//input.dispatchEvent(changeEvent);
page->runJavaScript("var input = document.getElementById('kw'); input.value = 'Qt'; var event = new Event('input', { bubbles: true }); input.dispatchEvent(event); ");
page->runJavaScript("document.getElementById('su').click();");
}

6. 模拟自动点击按钮,以及获取JavaScript脚本执行后返回的值
QtWidgetsApplication1.h
#pragma once
#include <QtWidgets/QWidget>
#include "ui_QtWidgetsApplication1.h"
class QWebEngineView;
class QWebEnginePage;
class QtWidgetsApplication1 : public QWidget
{
Q_OBJECT
public:
QtWidgetsApplication1(QWidget *parent = nullptr);
~QtWidgetsApplication1();
public slots:
void onClicked();//百度网站
void onClicked2();//soundcloud网站
private:
Ui::QtWidgetsApplication1Class ui;
QWebEngineView* view;
QWebEnginePage* page;
};
QtWidgetsApplication1.cpp
#include "QtWidgetsApplication1.h"
#include <QtWebEngineWidgets>
#include <QWebEnginePage>
#include <QWebEngineView>
#include <qpushbutton.h>
QtWidgetsApplication1::QtWidgetsApplication1(QWidget *parent)
: QWidget(parent)
{
ui.setupUi(this);
setFixedSize(1050,650);
QPushButton* btn = new QPushButton("Btn");
btn->show();
connect(btn, &QPushButton::clicked ,this, &QtWidgetsApplication1::onClicked2);
view = new QWebEngineView(this);
view->setFixedSize(this->width(), this->height());
page = new QWebEnginePage(view);
view->setPage(page);
view->load(QUrl("https://soundcloud.com/"));
//view->load(QUrl("https://www.baidu.com/"));
view->show();
}
QtWidgetsApplication1::~QtWidgetsApplication1()
{
}
void QtWidgetsApplication1::onClicked2()
{
auto res = [=](const QVariant& result)
{
qDebug() << "The title of the webpage is:" << result;//获取js脚本执行后返回的结果
};
QString str = "sc-button-play playButton sc-button m-stretch";
page->runJavaScript("var btn = document.getElementsByClassName(\"playButton\"); btn[0].click(); ", res);
}
void QtWidgetsApplication1::onClicked()
{
auto res = [=](const QVariant& result)
{
qDebug() << "The title of the webpage is:" << result;//获取js脚本执行后返回的结果
};
page->runJavaScript("var btn = document.getElementById('su'); btn.click();", res);
}
JavaScript定位页面元素:
- 通过id获取
document.getElementById('id') # 获取的是单个
- 通过name获取
document.getElementsByName(“Name”)[0] # 获取的是多个返回的是list
- 通过标签名选取元素
document.getElementsByTagName(“tag”) # 获取的是多个
- 通过CLASS类选取元素
document.getElementsByClassName(“class”) # 获取的是多个
# 兼容性:IE8及其以下版本的浏览器未实现getElementsByClassName方法
- 通过CSS选择器选取元素
document.querySelector (“css selector”) # 获取的是单个
document.querySelectorAll(“css selector") # 获取的是多个
# 兼容性:IE8及其以下版本的浏览器只支持CSS2标准的选择器语法
1.2 QWebEngineView
QWebEngineView 是QT5.4版本加入的新浏览器引擎,QWebEngineView是Qt WebEngine网页浏览模块的主要窗口部件组件。它可以在各种应用程序中使用,实时显示来自互联网的网页内容。它使用了 Chromium 内核来渲染网页,因此可以很好地支持 HTML、CSS 和 JavaScript。
在windows系统下 QWebEngineView支持MSVC编译器编译、不支持mingw编译。
使用QWebEngineView时,需要在工程文件里增加webenginewidgets模块的引用,并加上#include <QWebEngineView> 头文件。
qmake:
QT += webenginewidgets
#include <QtWebEngineWidgets>
#include <QWebEngineView>
下面是来至官方文档翻译:
QWebEngineView类提供了一个用于查看和编辑web文档的小部件。 web视图是Qt WebEngine,它是web浏览模块的主要小部件组件。它可以用于各种应用程序中,以实时显示来自Internet的web内容。
QWebEngineView可以使用load()函数将网站加载到web视图,GET方法始终用于加载URL,与所有Qt小部件一样,必须调用show()函数才能显示web视图,或者可以使用setUrl()加载网站。如果HTML文件本地可用,可以改用setHtml()。
loadStarted()信号在视图开始加载时发出,loadProgress()信号在web视图的某个元素(如嵌入式图像或脚本)完成加载时发出。当视图完全加载时,会发出loadFinished()信号。它的参数(true或false)指示加载是成功还是失败。QWebEngineView包含一个QWebEnginePage,它反过来允许访问页面上下文中的QWebEngineHistory。
可以使用title()属性访问HTML文档的标题。此外,网站可以指定一个图标,可以使用icon()或使用iconUrl()属性访问该图标。如果标题或图标更改,将发出相应的titleChanged()、iconChanged()和iconUrlChanged()信号。zoomFactor()属性允许按比例因子缩放网页内容。
该小部件具有一个上下文菜单,可根据手头的元素进行定制,并包括在浏览器中有用的操作。对于自定义上下文菜单,或在菜单或工具栏中嵌入操作,可通过pageAction()使用单个操作。web视图维护返回操作的状态,但允许修改操作属性,如文本或图标。动作语义也可以通过triggerPageAction()直接触发。如果要为允许用户打开新窗口(如弹出窗口)的网站提供支持,可以将QWebEngineView子类化并重新实现createWindow()函数。
QWebEngineView简单使用的示例代码:
QWebEngineView *view = new QWebEngineView(parent);
view->load(QUrl("http://qt-project.org/"));
view->show();
QWebEngineView类常用的几个接口介绍:
公共的函数:
//1. 网页上查找文本
void findText(const QString &subString, QWebEnginePage::FindFlags options = ..., const QWebEngineCallback<bool> &resultCallback = ...)
//返回当前选定的文本
QString selectedText() const
//2. 此属性保存此页面是否包含选定内容。
bool hasSelection() const
//3. 返回指向已导航网页的视图历史记录的指针。
QWebEngineHistory *history() const
//4. 返回当前网页图标
QIcon icon() const
//5. 返回当前网页图标地址
QUrl iconUrl() const
//6. 加载新的网页地址
void load(const QUrl &url)
//7. 加载新的请求
void load(const QWebEngineHttpRequest &request)
//8. 返回指向当前网页的指针。
QWebEnginePage *page() const
//9. 返回指向封装指定web操作的QAction的指针。
QAction *pageAction(QWebEnginePage::WebAction action) const
//10. 将web视图的内容设置为数据
void setContent(const QByteArray &data, const QString &mimeType = QString(), const QUrl &baseUrl = QUrl())
//11. 设置HTML内容
void setHtml(const QString &html, const QUrl &baseUrl = QUrl())
//12. 设置页: 使网页成为web视图的新网页。
void setPage(QWebEnginePage *page)
//13. 设置新的地址
void setUrl(const QUrl &url)
QUrl url() const
//14. 设置缩放属性
void setZoomFactor(qreal factor)
qreal zoomFactor() const
//15.返回指向视图或页面特定设置对象的指针。
QWebEngineSettings *settings() const
//16. 当前网页标题
QString title() const
//17. 触发指定的操作。
void triggerPageAction(QWebEnginePage::WebAction action, bool checked = false)
//方便的槽函数:
void back() //返回上一步页面-没有就没反应
void forward() //返回下一步页面-没有就没反应
void reload() //重新加载当前网页-刷新网页
void stop() //停止网页加载
//可以关联的信号:
//1. 图标发生改变
void iconChanged(const QIcon &icon)
void iconUrlChanged(const QUrl &url)
//2. 加载完成
void loadFinished(bool ok)
//3. 加载进度 0~100
void loadProgress(int progress)
//4. 该信号在页面的新加载开始时发出。
void loadStarted()
//5. 当渲染过程以非零退出状态终止时,将发出此信号。terminationStatus是进程的终止状态,exitCode是进程终止时使用的状态代码。
void renderProcessTerminated(QWebEnginePage::RenderProcessTerminationStatus terminationStatus, int exitCode)
//6. 只要选择发生变化,就会发出该信号。
注意:当使用鼠标通过左键单击和拖动选择文本时,将为每个选定的新字符发出信号,而不是释放鼠标左键。
void selectionChanged()
//7. 标题改变
void titleChanged(const QString &title)
//8. url改变
void urlChanged(const QUrl &url)
1.3 实现简易浏览器

widget.h
#ifndef WIDGET_H
#define WIDGET_H
#include <QWidget>
#include <QWebEngineView>
QT_BEGIN_NAMESPACE
namespace Ui { class Widget; }
QT_END_NAMESPACE
class Widget : public QWidget
{
Q_OBJECT
public:
Widget(QWidget *parent = nullptr);
~Widget();
private slots:
void slot_iconChanged(const QIcon &icon);
void slot_loadProgress(int progress);
void slot_titleChanged(const QString &title);
void on_new_clicked();
void on_load_clicked();
void on_stop_clicked();
void on_up_clicked();
void on_dn_clicked();
private:
Ui::Widget *ui;
QWebEngineView *m_webView;
};
#endif // WIDGET_H
widget.cpp
#include "widget.h"
#include "ui_widget.h"
Widget::Widget(QWidget *parent)
: QWidget(parent)
, ui(new Ui::Widget)
{
ui->setupUi(this);
//new 一个QWebEngineView
m_webView = new QWebEngineView(this);
//添加到布局器
ui->verticalLayout->addWidget(m_webView);
//关联信号
connect(m_webView, SIGNAL(iconChanged(const QIcon &)), this, SLOT(slot_iconChanged(const QIcon &)));
connect(m_webView, SIGNAL(loadProgress(int)), this, SLOT(slot_loadProgress(int)));
connect(m_webView, SIGNAL(titleChanged(const QString &)), this, SLOT(slot_titleChanged(const QString &)));
ui->progressBar->setMaximum(100);
ui->progressBar->setMinimum(0);
}
Widget::~Widget()
{
delete ui;
}
//刷新网页
void Widget::on_new_clicked()
{
ui->progressBar->setValue(0);
m_webView->reload();
}
//加载新页面
void Widget::on_load_clicked()
{
QString url=ui->lineEdit->text();
if(!url.isEmpty())
{
ui->progressBar->setValue(0);
m_webView->load(QUrl(url));
}
}
//停止
void Widget::on_stop_clicked()
{
m_webView->stop();
}
//上一页
void Widget::on_up_clicked()
{
m_webView->back();
}
//下一页
void Widget::on_dn_clicked()
{
m_webView->forward();
}
//图标改变
void Widget::slot_iconChanged(const QIcon &icon)
{
this->setWindowIcon(icon);
}
//加载进度
void Widget::slot_loadProgress(int progress)
{
ui->progressBar->setValue(progress);
}
//标题改变
void Widget::slot_titleChanged(const QString &title)
{
this->setWindowTitle(title);
}
widget.ui

1.4 编译报错问题
注意: 如果编译一直报下面错误

查资料常见原因以下三种:
1)QT版本过低。需要QT版本号为QT5.5版本及其以上。从Qt5.5开始,Qt WebKit模块被废弃,取而代之的是Qt WebEngine模块。且只有MSVC才支持该模块。
2)没有安装WebEngine库。在安装QT文件夹里有一个MaintenanceTool.exe应用程序,你可以更新和查看是否安装了WebEngine。

3)所使用的编译器不对。我遇到的就是这个原因。许多资料上写MSVC 2013及其以上版本构建,就可以支持Qt WebEngine。但我使用MSVC 2013不可以,并且MaintenanceTool.exe查看WebEngine显示只有msvc2017才支持,如下图

解决办法就是给QT配置 msvc2017的开发环境。

浙公网安备 33010602011771号