WebView2嵌入Qt以使用Edge替代webEngine(Qt添加外部运行库,以WebView2为例)


日志:1. 最近学习做项目时深感webEngine加载网页的缓慢和编译后的臃肿,所以尝试着使用WebView2调用Edge浏览器来减减负。
2. 想要添加其他运行库同样可以参照此方法

1. 下载组件

  1. Microsoft Edge WebView2
  2. WebView2Samples,此为WebView2所有功能的示例工程(可以选择不下载)。

2. 获取WebView2包

有两种方法供选择,一种是直接解压缩.nupkg支持包,另一种是使用vs打开WebView2Samples中的示例工程后安装NuGet程序包获取。

方法一. 直接解压缩.nupkg支持包

进入网页后点击右侧的下载按钮,来下载下面两个支持包
Microsoft.Web.WebView2.1.0.902.49
Microsoft.Windows.ImplementationLibrary.1.0.191107.2

下载后发现是.nupkg文件,可以直接使用解压缩软件解压。这里我使用Bandizip解压缩。
`Microsoft.Web.WebView2.1.0.902.49

方法二. 使用vs安装NuGet程序包获取

打开下载的WebView2Samples示例包,打开如下路径(WebView2Samples\GettingStartedGuides\Win32_GettingStarted),此为WebView2Samples的原始示例工程。使用vs打开此示例工程,这里借鉴微软官方的配置教程,Win32 应用中的 WebView2 入门
Win32_GettingStarted
在使用<管理 NuGet程序包>安装必要组件后,此时打开工程目录会发现多了一个packages文件夹。
WebView2Samples\GettingStartedGuides\Win32_GettingStarted

最终,我们可以得到下面两个运行WebView2的必要支持包。

必要支持包

3. 嵌入Qt工程

如何新建一个Qt工程这里不再赘述,我们直接开始嵌入WebView2。

将WebView2加入Qt编译

  1. 将packages包复制到所在工程路径,我的复制在external/packages处。
    packages包路径

  2. 这里我使用CMake嵌入,至于Qt的qmake工程可以借鉴CMakeLists.txt文件,应该能够很轻松的嵌入。
    下面是需要在CMakeLists.txt添加的内容。Map_Upper_Computer为我的项目的名称。

# 设置扩展包路径,CMAKE_CURRENT_SOURCE_DIR为工程所在路径,一般默认包含子啊工程中,不必额外设置。
set(CMAKE_EXTERNAL_PACKAGES ${CMAKE_CURRENT_SOURCE_DIR}/external/packages)
# 添加扩展包头文件目录。一般运行库所需的头文件
include_directories(${CMAKE_EXTERNAL_PACKAGES}/Microsoft.Web.WebView2.1.0.2957.106/build/native/include)
include_directories(${CMAKE_EXTERNAL_PACKAGES}/Microsoft.Windows.ImplementationLibrary.1.0.240803.1/include)
# 添加扩展包库目录,根据自身所在平台选择arm64/x64/x86,为lib文件所在目录
link_directories(${CMAKE_EXTERNAL_PACKAGES}/Microsoft.Web.WebView2.1.0.2957.106/build/native/x64)

# 链接lib文件可以和原有的合并,即
target_link_libraries(Map_Upper_Computer PRIVATE
    Qt${QT_VERSION_MAJOR}::Widgets
    Qt${QT_VERSION_MAJOR}::WebEngineWidgets
    Qt${QT_VERSION_MAJOR}::WebEngineCore
    Qt${QT_VERSION_MAJOR}::SerialPort
    Qt${QT_VERSION_MAJOR}::Qml
    Qt${QT_VERSION_MAJOR}::Quick
    WebView2LoaderStatic.lib
    WebView2Loader.dll.lib
)

运行示例工程

这里给出嵌入项目的示例代码,有些简陋,验证是否移植成功,主打一个能用就行。
头文件

#ifndef MAPWEB_H
#define MAPWEB_H

#include <QWidget>
#include <QProcess>
#include <windows.h>
#include <wrl.h>
#include <wil/com.h>
#include <WebView2.h>
#include <QResizeEvent>

using namespace Microsoft::WRL;

namespace Ui {
	class mapWeb;
}

class mapWeb : public QWidget
{
	Q_OBJECT

public:
	explicit mapWeb(QWidget* parent = nullptr);
	~mapWeb();

private:
	Ui::mapWeb* ui;

	wil::com_ptr<ICoreWebView2Controller> webviewController;
	wil::com_ptr<ICoreWebView2> webview;

	void initializeWebView2();
	void resizeEvent(QResizeEvent* event);

};

#endif // MAPWEB_H

源文件

#include "mapWeb.h"
#include "ui_mapweb.h"

mapWeb::mapWeb(QWidget* parent)
	: QWidget(parent), ui(new Ui::mapWeb)
{
	ui->setupUi(this);
	initializeWebView2();
}

mapWeb::~mapWeb()
{
	if (webviewController) {
		webviewController = nullptr;
	}
	if (webview) {
		webview = nullptr;
	}
	delete ui;
}

void mapWeb::initializeWebView2()
{
	HWND hwnd = (HWND)this->winId();

	//  WebView2 用户数据存储路径
	LPCWSTR userDataFolder = L"C:\\ProgramData\\Cache";

	// 创建 WebView2 控制器
	CreateCoreWebView2EnvironmentWithOptions(nullptr, userDataFolder, nullptr,
		Callback<ICoreWebView2CreateCoreWebView2EnvironmentCompletedHandler>(
			[this, hwnd](HRESULT result, ICoreWebView2Environment* env) -> HRESULT
			{
				if (FAILED(result)) {
					qDebug() << "WebView2 环境创建失败: " << result;
					return result;
				}

				env->CreateCoreWebView2Controller(hwnd, Callback<ICoreWebView2CreateCoreWebView2ControllerCompletedHandler>(
					[this, hwnd](HRESULT result, ICoreWebView2Controller* controller) -> HRESULT
					{
						if (FAILED(result) || !controller) {
							qDebug() << "WebView2 控制器创建失败: " << result;
							return result;
						}

						webviewController = controller;
						webviewController->get_CoreWebView2(&webview);
						// 设置创建的框体的大小
						RECT bounds;
						GetClientRect(hwnd, &bounds);
						webviewController->put_Bounds(bounds);

						webview->Navigate(L"https://www.bing.com");

						return S_OK;
					}).Get());

				return S_OK;
			}).Get());
}
// 监视框体变动以实时更改界面大小
void mapWeb::resizeEvent(QResizeEvent* event)
{
	if (webviewController) {
		RECT bounds;
		GetClientRect((HWND)this->winId(), &bounds);
		webviewController->put_Bounds(bounds);
	}
	QWidget::resizeEvent(event);
}

QT5是一个跨平台的应用程序开发框架,它允许开发使用C++编写应用程序,并提供丰富的图形用户界面组件。WebEngine模块(也称为Qt WebEngineWebView2前身)是QT5中用于嵌入Web浏览器的功能,特别是在QML(Qt Meta Language)环境中。 在QT5中使用WebEngine,你可以创建一个案,比如构建一个桌面应用,这个应用有一个区域可以显示网页内容。以下是简单的步骤: 1. **设置环境**:首先确保你已经安装了QT5以及支持WebEngine开发的版本。如果你的QT版本较旧,可能需要升级到QT5.14或更高版本,以便包含WebEngine的支持。 2. **添加依赖**:在`qmake.pro`文件中,确保包含了`Qt5WebEngineWidgets`模块,这是使用WebEngine的基本库。 ```pro QT += webenginewidgets ``` 3. **基本结构**:创建一个QML文件,如`main.qml`,并在其中使用`QtQuick.Controls`库创建一个WebView2控件: ```qml import QtQuick 2.15 import QtQuick.Controls 2.15 ApplicationWindow { visible: true width: 640 height: 480 title: "Web View Example" WebView2 { id: webView anchors.fill: parent source: "https://www.example.com" } } ``` 4. **集成到C++项目**:在C++部分,你需要处理窗口的生命周期管理,并加载并显示QML文件: ```cpp #include <QQmlApplicationEngine> // ... QQmlApplicationEngine engine; engine.load(QUrl(QStringLiteral("qrc:/main.qml"))); // 运行主循环 int main(int argc, char *argv[]) { return app.exec(); } ``` 在这个子中,用户界面通过QML呈现,而C++负责初始化引擎并加载QML文件,使得Web内容能在桌面应用程序中动态展示。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值