QT5 通过 webview2 加载网页

news2024/9/26 1:20:05

官方文档参考:https://learn.microsoft.com/zh-cn/microsoft-edge/webview2/get-started/win32

Webview2依赖的头文件和库

头文件主要为:WebView2和WixLibrary,存储在include/external
[图片]
[图片]

库主要为:WebView2LoaderStatic.lib和WebView2Loader.dll,存储在lib/external
[图片]

初始化项目加载webview2

CMakeLists文件

#工程名
project(uXXXXSoftware)

#cmake最低版本
cmake_minimum_required(VERSION 3.17)

#设定cmake模块的路径
set(CMAKE_MODULE_PATH
        ${PROJECT_SOURCE_DIR}/cmake # 项目cmake
        ${PROJECT_SOURCE_DIR}/cmake/base # 通用cmake
        ${CMAKE_MODULE_PATH})

#加载配置项
include(set_env)

#加载项目配置
include(init_project)

#加载编译配置
include(set_compile_arg)

base/set_env.cmake

message(STATUS "====================set_env.cmake===================")

# 处理编译字符集问题
add_compile_options("$<$<C_COMPILER_ID:MSVC>:/utf-8>")
add_compile_options("$<$<CXX_COMPILER_ID:MSVC>:/utf-8>")

#C++标准
set(CMAKE_CXX_STANDARD 11)

# 开启QT用于预处理的组件
set(CMAKE_AUTOMOC ON)
set(CMAKE_AUTORCC ON)
set(CMAKE_AUTOUIC ON)

#设置全局系统变量
set(PROJECT_EXTERNAL_DIR "D:/MyCPP")
set(PROJECT_EXTERNAL_INCLUDE_DIR "${PROJECT_EXTERNAL_DIR}/include/external")
set(PROJECT_EXTERNAL_LIB_DIR "${PROJECT_EXTERNAL_DIR}/lib/external")
message(STATUS "PROJECT_EXTERNAL_INCLUDE_DIR is ${PROJECT_EXTERNAL_INCLUDE_DIR}")
message(STATUS "PROJECT_EXTERNAL_LIB_DIR is ${PROJECT_EXTERNAL_LIB_DIR}")

#配置QT位置
message(STATUS "CMAKE_SYSTEM_NAME is ${CMAKE_SYSTEM_NAME}")
if (CMAKE_SYSTEM_NAME MATCHES "Windows")
    #下面是Windows下Qt的默认前缀
    set(CMAKE_PREFIX_PATH "D:/Library/Qt5.14.2/5.14.2/msvc2017_64/lib/cmake")
elseif (CMAKE_SYSTEM_PROCESSOR MATCHES "aarch64" AND CMAKE_SYSTEM_NAME MATCHES "Linux")
    #下面是aarch64 Linux下Qt的默认前缀
    set(CMAKE_PREFIX_PATH /opt/Qt5.14.2_aarch64/)
elseif (CMAKE_SYSTEM_NAME MATCHES "Linux")
    #下面是Linux x64下Qt的默认前缀
    set(CMAKE_PREFIX_PATH /opt/Qt5.14.2/5.14.2/gcc_64)
endif ()
message(STATUS "CMAKE_PREFIX_PATH is ${CMAKE_PREFIX_PATH}")

message(STATUS "====================set_env.cmake end===================")

init_project.cmake

message(STATUS "====================init_project.cmake===================")

# 查找QT的模块
find_package(Qt5 COMPONENTS
        Core
        Gui
        Widgets
        REQUIRED)

#外部头文件的路径
include_directories(SYSTEM
        ${PROJECT_EXTERNAL_INCLUDE_DIR}
)
#外部库文件的路径
link_directories(${PROJECT_EXTERNAL_LIB_DIR})

# 把目录Packages/MainFrame/src下面的所有文件作为变量存储
aux_source_directory(Packages/MainFrame/src SOURCES)
# 添加源文件
add_executable(uXXXXSoftware ${SOURCES})

# 添加模块
target_link_libraries(uXXXXSoftware 
        Qt5::Core
        Qt5::Gui
        Qt5::Widgets
        WebView2LoaderStatic
)

message(STATUS "====================init_project.cmake end===================")

base/set_compile_arg.cmake

message(STATUS "====================set_compile_arg.cmake===================")

# 默认的编译配置(可选)
if (WIN32 AND NOT DEFINED CMAKE_TOOLCHAIN_FILE)
    set(DEBUG_SUFFIX)
    if (MSVC AND CMAKE_BUILD_TYPE MATCHES "Debug")
        set(DEBUG_SUFFIX "d")
    endif ()
    set(QT_INSTALL_PATH "${CMAKE_PREFIX_PATH}")
    if (NOT EXISTS "${QT_INSTALL_PATH}/bin")
        set(QT_INSTALL_PATH "${QT_INSTALL_PATH}/..")
        if (NOT EXISTS "${QT_INSTALL_PATH}/bin")
            set(QT_INSTALL_PATH "${QT_INSTALL_PATH}/..")
        endif ()
    endif ()
    if (EXISTS "${QT_INSTALL_PATH}/plugins/platforms/qwindows${DEBUG_SUFFIX}.dll")
        add_custom_command(TARGET ${PROJECT_NAME} POST_BUILD
                COMMAND ${CMAKE_COMMAND} -E make_directory
                "$<TARGET_FILE_DIR:${PROJECT_NAME}>/plugins/platforms/")
        add_custom_command(TARGET ${PROJECT_NAME} POST_BUILD
                COMMAND ${CMAKE_COMMAND} -E copy
                "${QT_INSTALL_PATH}/plugins/platforms/qwindows${DEBUG_SUFFIX}.dll"
                "$<TARGET_FILE_DIR:${PROJECT_NAME}>/plugins/platforms/")
    endif ()
    foreach (QT_LIB Core Gui Widgets)
        add_custom_command(TARGET ${PROJECT_NAME} POST_BUILD
                COMMAND ${CMAKE_COMMAND} -E copy
                "${QT_INSTALL_PATH}/bin/Qt5${QT_LIB}${DEBUG_SUFFIX}.dll"
                "$<TARGET_FILE_DIR:${PROJECT_NAME}>")
    endforeach (QT_LIB)
endif ()

message(STATUS "====================set_compile_arg.cmake end===================")

main函数

#pragma execution_character_set("utf-8")

#include <QApplication>
#include <QFont>
#include "main_windows.h"

int main(int argc, char *argv[]) {
    QApplication a(argc, argv);

    //设置字体
    QFont font;
    font.setFamily("Microsoft Yahei UI");
    font.setPixelSize(13);
    a.setFont(font);

    MainWindow mainWindow;
    mainWindow.show();

    return QApplication::exec();
}

MainWindow函数

#include "main_windows.h"
#include "main_windows_layout.h"
#include "web_display_widget.h"


MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent) {
    this->setWindowTitle("XXXX");
    this->resize(1024, 960);

    QWidget* centralWidget = new QWidget(this);
    auto webview2Widget = new WebDisplayWidget(centralWidget);
    webview2Widget->resize(1024, 960);
    this->setCentralWidget(centralWidget);
}

WebDisplayWidget,显示web的widget核心函数
web_display_widge.h

#pragma execution_character_set("utf-8")


#include <wrl.h>
#include <QWidget>
#include "WixLibrary/wil/com.h"
#include "WebView2/WebView2.h"

class WebDisplayWidget : public QWidget {
public:
    WebDisplayWidget(QWidget *parent = nullptr);

    ~WebDisplayWidget() override;

public:
    HRESULT OnEnvironmentCompleted(HRESULT result, ICoreWebView2Environment *env);

    HRESULT OnControllerCompleted(HRESULT result, ICoreWebView2Controller *controller);

    HRESULT OnNavigationStarting(ICoreWebView2 *sender, ICoreWebView2NavigationStartingEventArgs *args);

    HRESULT OnNavigationCompleted(ICoreWebView2 *sender, ICoreWebView2NavigationCompletedEventArgs *args);

    HRESULT OnWebResourceRequested(ICoreWebView2 *sender, ICoreWebView2WebResourceRequestedEventArgs *args);

private:
    void InitWebView2();

private:
    wil::com_ptr<ICoreWebView2Controller> m_webViewController;
    wil::com_ptr<ICoreWebView2> m_webView;

    EventRegistrationToken m_navigationStartingToken;
    EventRegistrationToken m_navigationCompletedToken;
    EventRegistrationToken m_webResourceRequestedToken;
};

web_display_widget.cpp

#include "web_display_widget.h"

WebDisplayWidget::WebDisplayWidget(QWidget *parent) : QWidget(parent) {
    InitWebView2();
}


WebDisplayWidget::~WebDisplayWidget() {

}

void WebDisplayWidget::InitWebView2() {
    CreateCoreWebView2EnvironmentWithOptions(nullptr, nullptr, nullptr,
                                             Microsoft::WRL::Callback<ICoreWebView2CreateCoreWebView2EnvironmentCompletedHandler>(
                                                     [this](HRESULT result, ICoreWebView2Environment *env) -> HRESULT {
                                                         return OnEnvironmentCompleted(result, env);
                                                     }
                                             ).Get());
}

HRESULT WebDisplayWidget::OnEnvironmentCompleted(HRESULT result, ICoreWebView2Environment *env) {
    env->CreateCoreWebView2Controller(reinterpret_cast<HWND>(this->winId()),
                                      Microsoft::WRL::Callback<ICoreWebView2CreateCoreWebView2ControllerCompletedHandler>(
                                              [this](HRESULT result, ICoreWebView2Controller *controller) -> HRESULT {
                                                  return OnControllerCompleted(result, controller);
                                              }).Get());

    return S_OK;
}

HRESULT WebDisplayWidget::OnControllerCompleted(HRESULT result, ICoreWebView2Controller *controller) {
    if (controller == nullptr) {
        return S_FALSE;
    }

    //初始化webview2的依赖对象
    m_webViewController = controller;
    m_webViewController->get_CoreWebView2(&m_webView);

    //定义窗口
    RECT rect = {0, 0, this->width(), this->height()};
    m_webViewController->put_Bounds(rect);

    //导航地址
    m_webView->Navigate(L"https://www.baidu.com");

    //开始
    m_webView->add_NavigationStarting(
            Microsoft::WRL::Callback<ICoreWebView2NavigationStartingEventHandler>(
                    [this](ICoreWebView2 *webview, ICoreWebView2NavigationStartingEventArgs *args) -> HRESULT {
                        return OnNavigationStarting(webview, args);
                    }).Get(), &m_navigationStartingToken);

    //完成
    m_webView->add_NavigationCompleted(
            Microsoft::WRL::Callback<ICoreWebView2NavigationCompletedEventHandler>(
                    [this](ICoreWebView2 *webview, ICoreWebView2NavigationCompletedEventArgs *args) -> HRESULT {
                        return OnNavigationCompleted(webview, args);
                    }).Get(), &m_navigationCompletedToken);

    m_webView->add_WebResourceRequested(
            Microsoft::WRL::Callback<ICoreWebView2WebResourceRequestedEventHandler>(
                    [this](ICoreWebView2 *webview, ICoreWebView2WebResourceRequestedEventArgs *args) -> HRESULT {
                        return OnWebResourceRequested(webview, args);
                    }).Get(), &m_webResourceRequestedToken);
    return 0;
}

HRESULT WebDisplayWidget::OnNavigationStarting(ICoreWebView2 *sender, ICoreWebView2NavigationStartingEventArgs *args) {
    return S_OK;
}

HRESULT
WebDisplayWidget::OnNavigationCompleted(ICoreWebView2 *sender, ICoreWebView2NavigationCompletedEventArgs *args) {
    return S_OK;
}

HRESULT
WebDisplayWidget::OnWebResourceRequested(ICoreWebView2 *sender, ICoreWebView2WebResourceRequestedEventArgs *args) {
    return S_OK;
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1151608.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

C++——类和对象(构造函数与析构函数)

构造函数与析构函数 本章思维导图&#xff1a; 注&#xff1a;本章思维导图对应的Xmind文件和.png文件都已导入到”资料“中 1. 构造函数 以前&#xff0c;我们写一个Date类一般是这么写的&#xff1a; class Date { public :void Init(int year, int month, int day){_year…

Unity Animator cpu性能测试

测试案例&#xff1a; 场景中共有4000个物体&#xff0c;挂在40个animtor 上&#xff0c;每个Animator控制100个物体的动画。 使用工具&#xff1a; Unity Profiler. Unity 版本&#xff1a; unity 2019.4.40f1 测试环境&#xff1a; 手机 测试过程&#xff1a; 没有挂…

解读电力系统中的GPS北斗卫星同步时钟系统

随着电力系统的快速发展,变电站中的各类系统 &#xff1a;计算机监控系统、水情测报系统、视频监控系统 状态监测系统 生产信息管理系统等&#xff0c;各类装置&#xff1a;继电保护装置、故障录波装置、PMU装置、事件顺序记录SOE功能越来越强大&#xff0c;需要采集、记录的数…

CSS3背景样式

在CSS 2.1中&#xff0c;background属性的功能还无法满足设计的需求&#xff0c;为了方便设计师更灵活地设计需要的网页效果&#xff0c;CSS3在原有background基础上新增了一些功能属性&#xff0c;可以在同一个对象内叠加多个背景图像&#xff0c;可以改变背景图像的大小尺寸&…

LeetCode热题100 48.旋转图像

题目描述 给定一个 n n 的二维矩阵 matrix 表示一个图像。请你将图像顺时针旋转 90 度。 你必须在 原地 旋转图像&#xff0c;这意味着你需要直接修改输入的二维矩阵。请不要 使用另一个矩阵来旋转图像。 示例 1&#xff1a; 输入&#xff1a;matrix [[1,2,3],[4,5,6],[7,8,9…

2022年09月 Python(二级)真题解析#中国电子学会#全国青少年软件编程等级考试

Python等级考试&#xff08;1~6级&#xff09;全部真题・点这里 一、单选题&#xff08;共25题&#xff0c;每题2分&#xff0c;共50分&#xff09; 第1题 运行以下代码&#xff0c;结果输出的是&#xff1f;&#xff08; &#xff09; means[Thank,You] print(len(means))A…

Android开发知识学习——TCP / IP 协议族

文章目录 学习资源来自&#xff1a;扔物线TCP / IP 协议族TCP连接TCP 连接的建立与关闭TCP 连接的建立为什么要三次握手&#xff1f; TCP 连接的关闭为什么要四次挥手&#xff1f; 为什么要⻓连接&#xff1f; 常见面试题课后题 学习资源来自&#xff1a;扔物线 TCP / IP 协议…

潜力无限!深眸科技以工业视觉软硬件一体化解决方案深入应用场景

工业视觉作为智能制造的眼睛&#xff0c;在制造业各场景中具有广泛的应用前景&#xff0c;尤其是在检测、引导、定位、测量等方面应用需求不断提高。深眸科技为进一步巩固和加强技术领先优势&#xff0c;持续拓宽机器视觉技术的应用边界&#xff0c;通过先进的硬件设备和自研的…

86 最小栈

最小栈 题解1 STL大法好题解2 辅助最小栈&#xff08;直观&#xff0c;空间换时间&#xff09;题解3 不需要额外空间(!!!差值!!!) 设计一个支持 push &#xff0c;pop &#xff0c;top 操作&#xff0c;并能在常数时间内检索到最小元素的栈。 实现 MinStack 类: MinStack() 初…

支持「导入/导出」,应用迁移瞬间完成_三叠云

应用导入/导出 路径 应用管理 >> 创建新应用 功能简介 1. 应用程序支持「导出」功能&#xff0c;即将应用独立封装导出&#xff0c;用于三叠云系统内应用导入。 2. 应用程序支持「导入」功能&#xff0c;可以帮助用户将数据或文件导出到其他设备或应用程序中&#x…

思维导图在学习中的应用

思维导图在做学习中发挥着非常高效的作用&#xff0c;因为因为思维导图只有一页&#xff0c;所以需要准备和组织内容的时间会大大减少。并且思维导图的可视化的结构&#xff0c;可以让你瞬间将所有信息一览无余。而传统的笔记方法&#xff0c;会记录好几页。不仅信息冗杂&#…

【经典面试】87 字符串解码

字符串解码 题解1 递归(程序栈)——形式语言自动机(LL(1)) : O(S)另一种递归(直观) 题解2 2个栈(逆波兰式)1个栈(参考官方&#xff0c;但是不喜欢) 给定一个经过编码的字符串&#xff0c;返回它解码后的字符串。 编码规则为: k[encoded_string]&#xff0c;表示其中方括号内部的…

Linux 权限管理(二)

文件类型和访问权限&#xff08;事物属性&#xff09; linux前都会有一串这个字符&#xff0c;第二字符到第九字符分别表示拥有者&#xff0c;所属组&#xff0c;和other所对应的权限。那么第一个字符表示什么呢&#xff1f; 第一个字符表示文件类型&#xff1a; d&#xff1a…

开放式耳机百元价位推荐哪款比较好一点、最值得入手的开放式耳机

不知道有没有和我一样的朋友&#xff0c;在工作的时候喜欢带着耳机&#xff0c;享受音乐带来的愉悦。然而&#xff0c;传统的入耳式耳机在长时间佩戴时会给耳朵带来不适感&#xff0c;甚至损害听力。 因此我现在会使用开放式耳机&#xff0c;采用了开放式设计&#xff0c;不需…

流程封装与基于加密接口的测试用例设计

接口测试仅仅掌握 Requests 或者其他一些功能强大的库的用法&#xff0c;是远远不够的&#xff0c;还需要具备能根据公司的业务流程以及需求去定制化一个接口自动化测试框架的能力。所以&#xff0c;接下来&#xff0c;我们主要介绍下接口测试用例分析以及通用的流程封装是如何…

算法通关村第四关-青铜挑战基于链表完成栈

大家好我是苏麟 , 今天聊聊. 本期大纲 栈的基础知识栈的特征栈的操作Java中的栈 基于链表实现栈 栈的基础知识 栈的特征 栈和队列是比较特殊的线性表&#xff0c;又称之为访问受限的线性表。栈是很多表达式、符号等运算的基础&#xff0c;也是递归的底层实现。理论上递归能做…

进阶课5——人工智能数据分类

数据类型是指数据在计算机中的存储方式&#xff0c;根据数据的不同特征和表示方式&#xff0c;可以将数据分为不同的类型。在IT领域中&#xff0c;随着数字化信息技术的应用不断扩大&#xff0c;数据的种类和格式也越来越多。 从人机交互数据类型的视角来看&#xff0c;人工智…

RSA加密解密

生成公钥私钥&#xff1a; /*** RSA 生成公钥私钥*/ public class CreateSecrteKey {public static final String KEY_ALGORITHM "RSA";private static final String PUBLIC_KEY "RSAPublicKey";private static final String PRIVATE_KEY "RSAPri…

pytorch复现1_VGG

不涉及太多原理 VGG在2014年由牛津大学著名研究组VGG (Visual Geometry Group) 提出&#xff0c;斩获该年ImageNet竞赛中 Localization Task (定位任务) 第一名 和 Classification Task (分类任务) 第二名。 网络亮点&#xff1a; 1.通过堆叠多个3x3的卷积核来替代大尺度卷积核…