您现在的位置是:首页 > 技术文章网站首页技术文章

[CEF]Qt 嵌入 CEF

  • WangYe
  • 2021-03-27 14:05:18
  • 581 次阅读
实现 CEF 浏览器内核嵌入 Qt 中;

效果:

1616819289182638.png


步骤:

    CEF 编译教程点击我查看~

    1.先把 CEF Release 和 Debug 头文件 lib 和 dll 文件 单独存放到项目工程文件夹;

image.png

分别在 D:\Downloads\cef 89.0.12\Build\tests\cefsimple\ 中的 Release 和 Debug 文件夹中 (根据编译版本选择)

image.png

我把 dll 和 bin pak 放在工程文件夹 Third_party\cef\bin文件夹,lib 放在对应 lib 文件夹(编译的时候需要放置到编译文件夹中的)

头文件在 D:\Downloads\cef 89.0.12 中 include 文件夹 整个拷贝到 项目工程 D:\Demo\Third_party\cef 中

D:\Downloads\cef 89.0.12 \Release 或 Debug 中 libcef.lib (根据编译版本选择)

libcef_dll_wrapper.lib 库文件是在 生成编译 CEF 生成的 编译这个库要把 运行库设置改下 如下图:

image.pngimage.png

    2.配置头文件和库文件路径

image.pngimage.png

    3.把CEF项目中的 simple_app 和 simple_handler .h和.cc 拷贝到项目工程文件夹中;

image.png

源码区:

    stdafx.h

#include <QtWidgets>

/*CEF*/
#pragma comment(lib, "cef/lib/libcef.lib")
#pragma comment(lib, "cef/lib/libcef_dll_wrapper.lib")
#pragma comment(lib, "cef/lib/cef_sandbox.lib")
/*CEF END*/

#if defined(_MSC_VER) && (_MSC_VER >= 1600)  //预防中文乱码  
# pragma execution_character_set("utf-8")    
#endif

    Demo.h

#pragma once
#include "stdafx.h"
#include <QtWidgets/QWidget>

#include "simple_handler.h"
#include <WinUser.h>
#include <QDesktopWidget>
#include <QMessageBox>

class YunJiWan_Demo : public QWidget
{
    Q_OBJECT

public:
    YunJiWan_Demo(QWidget *parent = Q_NULLPTR);
protected:
    void InitUI();  //初始化界面
    void resizeEvent(QResizeEvent* event) override;    //CEF显示绘制
protected slots:

private:
    CefRefPtr<SimpleHandler> m_browserHander;
    QWidget* m_ThisWidget;

};

    Demo.h

#include "Demo.h"
#include "stdafx.h"

YunJiWan_Demo::YunJiWan_Demo(QWidget *parent)
    : QWindget(parent)
{
    InitUI();
}

void YunJiWan_Demo::InitUI()    //初始化界面
{
    /*加载QSS样式*/
	QFile file(":/YunJiWan_Demo/Res/Style.qss");    //资源文件
	file.open(QFile::ReadOnly);    //资源打开读取
	if (file.isOpen())
	{
		QString Skin = QObject::tr(file.readAll());
		qApp->setStyleSheet(Skin);
		file.close();
	}
    /*加载QSS样式 END*/

    QVBoxLayout* m_ThisLayout = new QVBoxLayout;

    m_ThisWidget = new QWidget(this);
    m_ThisWidget->setObjectName("ThisWidget");
    m_ThisWidget->setMinimumSize(1257, 792);
	/*CEF*/
	HWND wnd = (HWND)m_ThisWidget->winId();
	QString indexUrl = "http://www.baidu.com/";

	RECT winRect;
	QRect messageRect(0, 0, 1257, 792);

	winRect.left = messageRect.left();
	winRect.top = messageRect.top();
	winRect.right = messageRect.right();
	winRect.bottom = messageRect.bottom();

	CefWindowInfo cefWndInfo;
	cefWndInfo.SetAsChild(wnd, winRect);  //将cef界面嵌入qt界面中

	CefBrowserSettings cefBrowSetting;
	m_browserHander = CefRefPtr<SimpleHandler>(new SimpleHandler(false));
	bool browser = CefBrowserHost::CreateBrowser(cefWndInfo, m_browserHander, CefString(indexUrl.toStdWString()), cefBrowSetting, nullptr, nullptr);
	if (!browser)
	{
		QMessageBox::information(NULL, "warning", "brower create failed!");
	}
	/*CEF*/
    m_ThisLayout->addWidget(m_ThisWidget);

    this->setLayout(m_ThisLayout);
}

void YunJiWan_Demo::resizeEvent(QResizeEvent* event)
{
	QWidget::resizeEvent(event);

	if (!m_browserHander.get())
	{
		return;
	}

	std::list<CefRefPtr<CefBrowser> > cefBrowerList = m_browserHander->getCefBrowerList();
	if (cefBrowerList.size() == 0)
	{
		qDebug() << "cefBrowerList.size() == 0"; //第一次resizeEvent的时候,这个为0。Qt中resizeEvent只有在窗口显示出来后,才能获取到正确的窗口尺寸值。
		return;
	}

	CefRefPtr<CefBrowser> pBrower = cefBrowerList.front();

	if (pBrower.get())
	{
		HWND hwnd_ = pBrower->GetHost()->GetWindowHandle();
		if (hwnd_)
		{
			QSize browserSize = m_ThisWidget->size();
			::MoveWindow(hwnd_, 0, 0, browserSize.width(), browserSize.height(), TRUE);
		}
	}
}

    main.cpp

#include "Demo.h"
#include "stdafx.h"
#include <QtWidgets/QApplication>

#include "simple_app.h"
#include "simple_handler.h"

void QCefInitSettings(CefSettings& settings)
{
	//std::string cache_path = AppGetWorkingDirectory().toStdString() + "/.cache";//缓存地址
	// CefString(&settings.cache_path) = CefString(cache_path);
	settings.multi_threaded_message_loop = true;//多线程消息循环
	settings.log_severity = LOGSEVERITY_DISABLE;//日志
//  settings.single_process = true;

	settings.no_sandbox = true;//沙盒
}

int QCefInit(int& argc, char** argv)
{
	HINSTANCE hInstance = static_cast<HINSTANCE>(GetModuleHandle(nullptr));

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

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

	CefSettings settings;
	QCefInitSettings(settings);

	//CefInitialize(mainArgs, settings, app, nullptr);	//显示cefsimple窗口
	CefInitialize(mainArgs, settings, nullptr, nullptr);	//不显示cefsimple窗口

	return -1;
}

void CefQuit()
{
	CefShutdown();
}

int main(int argc, char *argv[])
{
    QApplication a(argc, argv);
	int result = QCefInit(argc, argv);
	if (result >= 0) {
		return result;
	}
    YunJiWan_Demo w;
    w.show();
    w.move((QApplication::desktop()->width() - w.width()) / 2, (QApplication::desktop()->height() - w.height()) / 2);   //窗口居中显示
	a.exec();
	CefQuit();
    return 0;
}
TAG: CEF Vs Qt

文章评论 (0)



Top