王海鱼 发表于 2025-3-8 01:43:45

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

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


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

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

进入网页后点击右侧的下载按钮,来下载下面两个支持包
Microsoft.Web.WebView2.1.0.902.49
Microsoft.Windows.ImplementationLibrary.1.0.191107.2
https://i-blog.csdnimg.cn/direct/e86a21087b5b4b88a416219c41c64f0e.png#pic_center
下载后发现是.nupkg文件,可以直接使用解压缩软件解压。这里我使用Bandizip解压缩。
https://i-blog.csdnimg.cn/direct/1cc91ac6037a45678ff0201775d1af3b.png#pic_center
方法二. 使用vs安装NuGet程序包获取

打开下载的WebView2Samples示例包,打开如下路径(WebView2Samples\GettingStartedGuides\Win32_GettingStarted),此为WebView2Samples的原始示例工程。使用vs打开此示例工程,这里借鉴微软官方的配置教程,Win32 应用中的 WebView2 入门。
https://i-blog.csdnimg.cn/direct/6acd2c3a34164584803df55d52d76884.png#pic_center
在使用<管理 NuGet程序包>安装必要组件后,此时打开工程目录会发现多了一个packages文件夹。
https://i-blog.csdnimg.cn/direct/3dfd63cee5534883992dd3a0c792762e.png#pic_center
最终,我们可以得到下面两个运行WebView2的必要支持包。

https://i-blog.csdnimg.cn/direct/edf9f509421740429c9a1cae32a00495.png#pic_center
3. 嵌入Qt工程

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


[*] 将packages包复制到地点工程路径,我的复制在external/packages处。
https://i-blog.csdnimg.cn/direct/e9d080134e5b4b1f82279208c603ec89.png#pic_center
[*] 这里我使用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>(
                        (HRESULT result, ICoreWebView2Environment* env) -> HRESULT
                        {
                                if (FAILED(result)) {
                                        qDebug() << "WebView2 环境创建失败: " << result;
                                        return result;
                                }

                                env->CreateCoreWebView2Controller(hwnd, Callback<ICoreWebView2CreateCoreWebView2ControllerCompletedHandler>(
                                        (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);
}


免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。
页: [1]
查看完整版本: WebView2嵌入Qt以使用Edge替代webEngine(Qt添加外部运行库,以WebView2为