qt集成cef QWidget

编译libcef_dll_wrapper

假设你已经编译出了libcef_dll_wrapper.lib(Debug和Release版本,并且对应版本的程序集类型分别是:MDd和MD):qt的运行时库是MDd类型的,因此cef3编译的时候也应该遵循这个运行时库的编译方方式;qt集成cef在windows和mac下编译_LIJIWEI0611的博客-CSDN博客_cef mac

本人编译的时32位release版本

新建一个cef_bin的文件夹:拷贝cef87(本人使用的cef版本):的include Resources Release文件夹到新建的cef_bin文件夹中

 

 

 同时将编译生成的Release 版本的libcef_dll_wrapper.lib拷贝到cef_bin/release目录:

将编译生成的Release 版本的libcef_dll_wrapper.lib的路径在:ef_binary_87.1.14+ga29e9a3+chromium-87.0.4280.141_windows32\build\libcef_dll_wrapper\Release\libcef_dll_wrapper.lib

 

这样cef_bin就准备好了:

QWidget中集成cef

1 首先qt_creator新建一个QWidget的工程

2 将cef_bin文件夹拷贝到工程下:

 

3 .pro文件中引入cef

 4 开始集成

代码结构:

simple_app  simple_handler 即 cef工程中cefSimple中的文件

cefwidget 是QWidget,集成了cef

cef_delegate 是QWidget 和simplehandle中间的桥梁,负责将simplehandle的回调传递给QWidget

cefwidget

#include "cefwidget.h"
#include "ui_cefwidget.h"

#include "include/cef_request_context.h"
#include "simple_handler.h"
#include <QTimer>
#include <QDebug>
#include <QWindow>
#include <QString>
#include <Windows.h>
#pragma comment(lib, "User32.lib")

CefWidget::CefWidget(QWidget *parent) :
    QWidget(parent),
    ui(new Ui::CefWidget)
{
    ui->setupUi(this);
    QTimer::singleShot(0,[this](){initView();});
}

CefWidget::~CefWidget()
{
    delete ui;
}



void CefWidget::initView(){
    CefWindowInfo cef_wnd_info;
    QString str_url = "http://www.baidu.com";
    RECT win_rect;
    QRect rect = this->geometry();
    win_rect.left = rect.left();
    win_rect.right = rect.right();
    win_rect.top = rect.top();
    win_rect.bottom = rect.bottom();
    qDebug() << rect;

    cef_wnd_info.SetAsChild((HWND)this->winId(), win_rect); //将cef界面嵌入qt界面中
    CefBrowserSettings cef_browser_settings;
    simple_handler_ = CefRefPtr<SimpleHandler>(new SimpleHandler());
    simple_handler_->setDelegate(this);
    CefBrowserHost::CreateBrowser(cef_wnd_info,
        simple_handler_,
        str_url.toStdString(),
        cef_browser_settings,
        nullptr,
        CefRequestContext::GetGlobalContext());



}

void CefWidget::resizeEvent(QResizeEvent *event) {

    resizeView();

}
void CefWidget::resizeView(){
    if (!simple_handler_ ) {
        return;
    }

    CefRefPtr<CefBrowser> browser = simple_handler_->GetCurrentBrowser();
    if (!browser)
    {
        return;
    }
    CefRefPtr<CefBrowserHost> host = browser->GetHost();
    if (!host) {
        return;
    }

    QRect rect = this->geometry();
    qreal ratio = this->windowHandle() ? this->windowHandle()->devicePixelRatio()
                                                : 1.0;



    HWND hwndCefBrowser = (HWND)(host->GetWindowHandle());
    if (hwndCefBrowser && ::IsWindow(hwndCefBrowser))
        ::MoveWindow(hwndCefBrowser, 0, 0, rect.width() * ratio, rect.height() * ratio, FALSE);
}

void CefWidget::OnBrowserLoadEnd(const std::string& url,int identifier,int status){
   qDebug()<< "CefWidget::OnBrowserLoadEnd" << QString(url.c_str())  ;
   resizeView();
}

main:

#include "include/cef_app.h"
#include "cefwidget.h"

#include <QtWidgets/QApplication>

#include "simple_app.h"

/**
 * 初始化QT以及CEF相关
 */
int init_qt_cef(int& argc, char** argv)
{
    const HINSTANCE h_instance = static_cast<HINSTANCE>(GetModuleHandle(nullptr));

    const CefMainArgs main_args(h_instance);
    const CefRefPtr<SimpleApp> app(new SimpleApp); //CefApp实现,用于处理进程相关的回调。

    const int exit_code = CefExecuteProcess(main_args, app.get(), nullptr);
    if (exit_code >= 0)
    {
        return exit_code;
    }

    // 设置配置
    CefSettings settings;
    settings.multi_threaded_message_loop = true; //多线程消息循环
    settings.log_severity = LOGSEVERITY_DISABLE; //日志
    settings.no_sandbox = true; //沙盒

    CefInitialize(main_args, settings, app, nullptr);

    return -1;
}


int main(int argc, char* argv[])
{
    QCoreApplication::setAttribute(Qt::AA_EnableHighDpiScaling);  // 解决高DPI下,界面比例问题
    QApplication a(argc, argv);
    const int result = init_qt_cef(argc, argv);
    if (result >= 0)
    {
        return result;
    }

    CefWidget w;
    w.show();
    a.exec();

    CefShutdown(); // 关闭CEF,释放资源

    return 0;
}

效果:

 小问题:在cef的OnLoadEnd回调到来之前,应该加载一个动画之类的,先不让cefview显示出来,此时的cef正在初始化,尺寸还不对;以后处理吧

运行:

将cef_bin目录下的Release Resources中的文件拷贝到qt生成的可执行文件的目录下,即可成功运行 

工程:

qt+cef集成demo-互联网文档类资源-CSDN下载

  • 1
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
CEF(Chromium Embedded Framework)是一个基于Chromium的开源框架,主要用于嵌入式浏览器应用程序的开发Qt是一个跨平台的C++应用程序开发框架,提供了许多GUI和多媒体功能。在以下步骤中,我们将介绍如何将CEFQt集成。 1. 下载CEF 首先,需要从CEF官网(https://cefsharp.github.io/)下载适合您操作系统的CEF版本。您可以选择标准版本或使用NuGet包。 2. 创建Qt项目 使用Qt Creator创建一个新的Qt项目。在项目设置中,确保您已选择正确的构建工具链和平台。在.pro文件中添加以下内容: ``` LIBS += -L/path/to/cef -lcef INCLUDEPATH += /path/to/cef ``` 其中,`/path/to/cef`是CEF的安装路径。 3. 集成CEFQt项目中,您可以使用CEF的C API或C++ API。在本例中,我们将使用C++ API。 首先,将CEF的C++头文件添加到Qt项目中。在您的Qt项目中创建一个新的C++源文件,并使用以下代码初始化CEF: ``` #include "include/cef_app.h" #include "include/cef_browser.h" #include "include/cef_client.h" class CefApplication : public CefApp, public CefBrowserProcessHandler { public: // Implement CefApp methods here }; CefRefPtr<CefApplication> app(new CefApplication); CefMainArgs mainArgs(argc, argv); CefInitialize(mainArgs, app, NULL); ``` 这将初始化CEF并创建一个CEF应用程序。 接下来,您需要创建一个CEF客户端类。客户端类处理浏览器事件和渲染进程事件。以下是一个简单的CEF客户端类: ``` class CefClientImpl : public CefClient, public CefLifeSpanHandler { public: // Implement CefClient and CefLifeSpanHandler methods here }; CefRefPtr<CefClientImpl> client(new CefClientImpl); ``` 最后,将CEF嵌入到Qt应用程序中。在Qt应用程序的主窗口中,将CEF嵌入到QWidget中: ``` CefWindowInfo windowInfo; windowInfo.SetAsChild(reinterpret_cast<cef_window_handle_t>(widget->winId()), CefRect(0, 0, width, height)); CefBrowserSettings browserSettings; CefBrowserHost::CreateBrowserSync(windowInfo, client.get(), "http://www.google.com", browserSettings, NULL); ``` 这将在Qt应用程序的QWidget中创建一个CEF浏览器。 4. 运行应用程序 现在,您可以运行Qt应用程序并查看CEF浏览器。使用Qt的GUI控件可以与CEF浏览器进行交互,例如在Qt窗口中显示CEF浏览器的网页内容,或在CEF浏览器中嵌入Qt控件。 注意:在集成CEF时,需要考虑QtCEF的线程模型。Qt使用主线程作为GUI线程,而CEF使用多个线程处理浏览器事件和渲染进程事件。因此,在使用CEF时,需要确保在正确的线程上执行GUI操作。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值