如何在C++ QT 程序中集成cef3开源浏览器组件去显示网页?

文章目录

      • 1. **准备工作**
        • 1.1 下载CEF3
        • 1.2 配置Qt项目
      • 2. **集成CEF3到Qt窗口**
        • 2.1 创建Qt窗口容器
        • 2.2 初始化CEF3
      • 3. **处理CEF3消息循环**
      • 4. **处理多进程架构**
      • 5. **完整代码示例**
        • `main.cpp`
      • 6. **常见问题**
        • 6.1 黑屏问题
        • 6.2 窗口嵌入失败
        • 6.3 多进程调试
      • 7.**Github源码参考**
      • 8.**参考博客**
      • 总结

在Qt C++程序中集成CEF3(Chromium Embedded Framework)以显示网页,需要以下步骤:


1. 准备工作

1.1 下载CEF3
  • 从CEF官方网站下载预编译的CEF3二进制包(选择Standard版本)。
  • 解压后,目录结构通常包含:
    cef_binary/├── include/          # CEF头文件├── Release/          # 动态库文件(.dll/.so)├── Resources/        # 浏览器资源文件(如 locales、swiftshader)└── libcef_dll/       # CEF的C++包装库
    
1.2 配置Qt项目
  • 在Qt项目文件(.pro)中添加CEF3的依赖:
    # 指定CEF3头文件路径
    INCLUDEPATH += $$PWD/cef_binary/include# 添加CEF3库路径(根据平台选择)
    win32 {LIBS += -L$$PWD/cef_binary/Release -lcef -lcef_dll_wrapper
    }
    linux {LIBS += -L$$PWD/cef_binary/Release -lcef -lcef_dll_wrapper -lX11
    }# 复制CEF3资源文件到输出目录(避免运行时黑屏)
    QMAKE_POST_LINK += $$escape_expand(\n) cp -r $$PWD/cef_binary/Resources/* $$OUT_PWD/
    

2. 集成CEF3到Qt窗口

2.1 创建Qt窗口容器

CEF3需要通过原生窗口句柄(如HWNDXWindow)嵌入到Qt界面中。使用QWindowwinId()获取句柄:

#include <QMainWindow>
#include <QWindow>class BrowserWindow : public QMainWindow {Q_OBJECT
public:BrowserWindow(QWidget* parent = nullptr) : QMainWindow(parent) {// 创建一个空白的QWidget作为浏览器容器QWidget* container = new QWidget(this);setCentralWidget(container);// 获取原生窗口句柄m_cefWindowHandle = (void*)container->winId();}private:void* m_cefWindowHandle;  // 用于传递给CEF3的窗口句柄
};
2.2 初始化CEF3

CEF3需要在主进程初始化,并在子进程中处理渲染:

#include "include/cef_app.h"
#include "include/cef_client.h"class SimpleBrowserClient : public CefClient, public CefLifeSpanHandler {
public:// 实现CefClient接口CefRefPtr<CefLifeSpanHandler> GetLifeSpanHandler() override { return this; }// 创建浏览器窗口void OnAfterCreated(CefRefPtr<CefBrowser> browser) override {// 浏览器创建完成}IMPLEMENT_REFCOUNTING(SimpleBrowserClient);
};// 初始化CEF3
int main(int argc, char* argv[]) {CefMainArgs args(argc, argv);CefSettings settings;settings.no_sandbox = true;  // 禁用沙箱(简化配置)// 初始化CEFCefInitialize(args, settings, nullptr, nullptr);// 启动Qt应用QApplication app(argc, argv);BrowserWindow window;window.show();// 创建浏览器实例CefWindowInfo window_info;window_info.SetAsChild((HWND)window.cefWindowHandle(), CefRect(0, 0, 800, 600));CefBrowserSettings browser_settings;CefRefPtr<SimpleBrowserClient> client(new SimpleBrowserClient);CefBrowserHost::CreateBrowser(window_info, client, "https://www.example.com", browser_settings, nullptr);// 运行Qt事件循环app.exec();// 关闭CEFCefShutdown();return 0;
}

3. 处理CEF3消息循环

CEF3需要定期处理消息循环,而Qt有自己的事件循环。在Qt中可以通过定时器驱动CEF3消息:

class BrowserWindow : public QMainWindow {Q_OBJECT
public:BrowserWindow(QWidget* parent = nullptr) : QMainWindow(parent) {// 创建一个定时器,每隔10ms处理CEF消息QTimer* timer = new QTimer(this);connect(timer, &QTimer::timeout, []() {CefDoMessageLoopWork();  // 处理CEF消息});timer->start(10);}
};

4. 处理多进程架构

CEF3默认使用多进程模型(主进程 + 子进程)。需要在程序启动时区分进程角色:

int main(int argc, char* argv[]) {CefMainArgs args(argc, argv);CefRefPtr<CefApp> app;// 判断是否是子进程if (CefExecuteProcess(args, app, nullptr) >= 0) {return 0;  // 子进程直接退出}// 主进程初始化CefSettings settings;settings.no_sandbox = true;CefInitialize(args, settings, app, nullptr);// ... Qt代码 ...
}

5. 完整代码示例

main.cpp
#include <QApplication>
#include <QTimer>
#include "include/cef_app.h"
#include "BrowserWindow.h"int main(int argc, char* argv[]) {CefMainArgs args(argc, argv);CefRefPtr<CefApp> app;// 处理子进程if (CefExecuteProcess(args, app, nullptr) >= 0) {return 0;}// 初始化CEFCefSettings settings;settings.no_sandbox = true;CefInitialize(args, settings, app, nullptr);// 启动Qt应用QApplication qtApp(argc, argv);BrowserWindow window;window.show();// 处理CEF消息循环QTimer cefTimer;QObject::connect(&cefTimer, &QTimer::timeout, []() {CefDoMessageLoopWork();});cefTimer.start(10);int ret = qtApp.exec();// 关闭CEFCefShutdown();return ret;
}

6. 常见问题

6.1 黑屏问题
  • 原因:CEF3资源文件(localesswiftshader)未正确复制到输出目录。
  • 解决:在Qt项目文件中添加资源复制命令:
    QMAKE_POST_LINK += $$escape_expand(\n) cp -r $$PWD/cef_binary/Resources/* $$OUT_PWD/
    
6.2 窗口嵌入失败
  • 原因:未正确传递窗口句柄。
  • 解决:确保使用QWidget::winId()获取句柄,并在CEF中调用SetAsChild
6.3 多进程调试
  • 子进程调试:通过--type=renderer参数启动子进程调试。

7.Github源码参考

https://github.com/tishion/QCefView

8.参考博客

https://blog.csdn.net/LF__plus/article/details/137793277
https://blog.csdn.net/weixin_38416696/article/details/111044995
https://juejin.cn/post/6981077794507718692

总结

通过上述步骤,可以在Qt应用中集成CEF3浏览器组件。关键点包括:

  1. 正确配置CEF3的库和资源文件。
  2. 使用QWidget::winId()获取原生窗口句柄。
  3. 通过定时器驱动CEF3消息循环。
  4. 处理多进程架构。

如果需要更复杂的交互(如JavaScript调用C++函数),需进一步实现CefV8HandlerCefRenderProcessHandler接口。

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

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

相关文章

【实用技能】如何借助3D文档控件Aspose.3D, 在Java中无缝制作 3D 球体

概述 创建 3D 球体是 3D 图形设计的一个基本方面。无论您是在开发游戏、模拟还是可视化&#xff0c;无缝创建 3D 球体模型的能力都至关重要。Aspose.3D通过提供强大的 3D 图形 SDK 在各个行业中发挥着重要作用。它允许开发人员轻松创建、操作和转换 3D 模型。此 SDK 对于希望将…

【Leetcode 热题 100】169. 多数元素

问题背景 给定一个大小为 n n n 的数组 n u m s nums nums&#xff0c;返回其中的多数元素。多数元素是指在数组中出现次数 大于 ⌊ n / 2 ⌋ \lfloor n/2 \rfloor ⌊n/2⌋ 的元素。 你可以假设数组是非空的&#xff0c;并且给定的数组总是存在多数元素。 数据约束 n n u…

Docker build时apt update失败

配置好dockerfile后&#xff0c;编译镜像docker build -t my-debian .报错&#xff1a; E: Release file for http://mirrors.org/debian/dists/bookworm-updates/InRelease is not valid yet (invalid for another 3h 15min 21s). Updates for this repository will not be a…

MySql数据库SQL编写规范注意事项

MySQL数据库SQL编写规范对于提高代码可读性、增强代码维护性、优化查询性能、减少错误发生、促进标准化和团队协作以及提升开发效率等方面都具有重要意义。因此&#xff0c;在开发过程中应严格遵守SQL编写规范&#xff0c;以确保代码的质量和效率。 以下是 MySQL 数据库 SQL 编…

Jenkins 使用教程:从入门到精通

在软件开发的复杂流程中&#xff0c;持续集成与持续交付&#xff08;CI/CD&#xff09;是提升开发效率和保障软件质量的核心实践。Jenkins 作为一款备受欢迎的开源自动化服务器&#xff0c;在 CI/CD 流程中发挥着举足轻重的作用。本文将深入、详细地介绍 Jenkins 的使用方法&am…

通过k8s请求selfsubjectrulesreviews查询权限

当前是通过kubelet进行查询 curl --cacert /etc/kubernetes/pki/ca.crt \ --cert /var/lib/kubelet/pki/kubelet-client-current.pem \ --key /var/lib/kubelet/pki/kubelet-client-current.pem \ -d - \ -H "Content-Type: application/json" \ -H Accept: applicat…

C语言基础系列【3】VSCode使用

前面我们提到过VSCode有多么的好用&#xff0c;本文主要介绍如何使用VSCode编译运行C语言代码。 安装 首先去官网&#xff08;https://code.visualstudio.com/&#xff09;下载安装包&#xff0c;点击Download for Windows 获取安装包后&#xff0c;一路点击Next就可以。 配…

windows安装WSL完整指南

本文首先介绍WSL&#xff0c;然后一步一步安装WSL及Ubuntu系统&#xff0c;最后讲解如何在两个系统之间访问和共享文件信息。通过学习该完整指南&#xff0c;能帮助你快速安装WSL&#xff0c;解决安装和使用过程中的常见问题。 理解WSL&#xff08;Windows Subsystem for Linux…

doris:MySQL 兼容性

Doris 高度兼容 MySQL 语法&#xff0c;支持标准 SQL。但是 Doris 与 MySQL 还是有很多不同的地方&#xff0c;下面给出了它们的差异点介绍。 数据类型​ 数字类型​ 类型MySQLDorisBoolean- 支持 - 范围&#xff1a;0 代表 false&#xff0c;1 代表 true- 支持 - 关键字&am…

【LeetCode 刷题】贪心算法(4)-区间问题

此博客为《代码随想录》贪心算法章节的学习笔记&#xff0c;主要内容为贪心算法区间问题的相关题目解析。 文章目录 55. 跳跃游戏45. 跳跃游戏 II452. 用最少数量的箭引爆气球435. 无重叠区间763. 划分字母区间56. 合并区间 55. 跳跃游戏 题目链接 class Solution:def canJu…

苹果公司宣布正式开源 Xcode 引擎 Swift Build145

2025 年 2 月 1 日&#xff0c;苹果公司宣布正式开源 Xcode 引擎 Swift Build145。 Swift 是苹果公司于 2014 年推出的一种开源编程语言&#xff0c;用于开发 iOS、iPadOS、macOS、watchOS 和 tvOS 等平台的应用程序。 发展历程 诞生&#xff1a;2014 年&#xff0c;苹果在全球…

PID 算法简介(C语言)

一、简介: PID是比例、积分、微分三个环节的组合,用来进行反馈控制。每个部分都有对应的系数,也就是Kp、Ki、Kd。PID 算法实现这三个部分的计算,然后综合起来得到控制输出。 二、PID控制器结构体: PID控制器结构体:包含PID参数(Kp, Ki, Kd);存储积分项和上一次误差;…

123,【7】 buuctf web [极客大挑战 2019]Secret File

进入靶场 太熟悉了&#xff0c;有种回家的感觉 查看源代码&#xff0c;发现一个紫色文件 点下看看 点secret 信息被隐藏了 要么源代码&#xff0c;要么抓包 源代码没有&#xff0c;抓包 自己点击时只能看到1和3处的文件&#xff0c;点击1后直接跳转3&#xff0c;根本不出…

HTTP协议学习大纲

第一阶段&#xff1a;HTTP基础概念 互联网与Web基础 理解Web工作原理&#xff1a;客户端-服务器模型URL与URI的结构及区别端口、协议、域名概念 HTTP协议概览 HTTP的作用与特点&#xff08;无状态、无连接、可扩展&#xff09;HTTP协议版本演进&#xff08;0.9 → 1.0 → 1.1 …

Formality:时序变换(五)(寄存器复制)

相关阅读 Formalityhttps://blog.csdn.net/weixin_45791458/category_12841971.html?spm1001.2014.3001.5482 一、引言 时序变换在Design Compiler的首次综合和增量综合中都可能发生&#xff0c;它们包括&#xff1a;时钟门控(Clock Gating)、寄存器合并(Register Merging)、…

我使用deepseek高效学习-分析外文网站Cron定时执行任务

最近在spring框架中 设置定时任务&#xff0c;有的末尾是星号有的是问号&#xff0c;有的是6位&#xff0c;有的是7位。就这个机会总结下cron表达式的使用&#xff0c;综合源代码中的crontab地址翻译分析&#xff0c;结合最近超爆的deepseek 提高学习效率&#xff0c;归纳总结出…

BurpSuite抓包与HTTP基础

文章目录 前言一、BurpSuite1.BurpSuite简介2.BurpSuite安装教程(1)BurpSuite安装与激活(2)安装 https 证书 3.BurpSuite使用4.BurpSuite资料 二、图解HTTP1.HTTP基础知识2.HTTP客户端请求消息3.HTTP服务端响应消息4.HTTP部分请求方法理解5.HTTPS与HTTP 总结 前言 在网络安全和…

华为交换机堆叠配置

一、CSS堆叠集群配置&#xff08;框式交换机&#xff09; 1、通过集群卡连接方式组建集群 [SwitchA] set css mode css-card \\配置集群卡连接方式 [SwitchA] set css id 1 \\配置成员交换机的集群ID(缺省值为1) [SwitchA] set css priority 100 \\配…

google 多模态aistudio Stream Realtime体验

参考&#xff1a; https://aistudio.google.com/live 使用gemini多模态能力&#xff0c;支持语音图像文字输入输出&#xff0c;实时交互体验 支持语音实时交互、摄像头加语音、屏幕视频语音 摄像头 屏幕共享

(文末提供数据集下载)ML.NET库学习001:基于PCA的信用卡异常检查之样本处理与训练

文章目录 (文末提供数据集下载)ML.NET库学习001&#xff1a;基于PCA的信用卡异常检查之样本处理与训练目标项目概述代码结构概述1. **主要类和文件**2. **命名空间和使用指令**3. **数据类 (TransactionObservation)**4. **主程序入口 (Main 方法)**5. **数据预处理 (DataPrepr…