Qt实现 内嵌CEF3制作浏览器(尾篇)

7 篇文章 1 订阅
2 篇文章 2 订阅

在上一篇 Qt实现 CEF制作浏览器(首篇) 中,编译了cefsimple,打开了浏览器,不过该浏览器是demo做例子用的,但是我们的目的是为了嵌入qt窗口中。

本篇将介绍如何将CEF生成的浏览器嵌入到qt中窗口使用。

认为大家有一定基础,所以不再介绍如何在vs中加载licef_dll_wrapper等库和cef头文件等。

目录

一、准备步骤

二、运行效果

三、主要代码

四、完整代码和库:


一、准备步骤

1、编译licef_dll_wrapper库,记得如下把运行库改为多线程DLL(MD),debug下改为MDd。

2、把simple_handler.cc和simple_handler.h拷贝到自己的项目src里,直接使用

3、注释掉以下不需要的函数。

4、找到wWinMain,这是cef初始化的相关代码,拷贝到自己的cef初始化代码中。

二、运行效果

三、主要代码

1、main函数

int main(int argc, char *argv[])
{
	//初始化cef
	bool flag = CefManager::instance()->CefInit();
	if (!flag) {
		return -1;
	}

    QApplication a(argc, argv);
    QtCef w;
    w.show();

    int ret = a.exec();

	CefManager::instance()->CefQuit();

	return ret;
}

对CEF的初始化和退出放在了一个全局静态类中,比较方便去维护和复用,初始化为什么放在main函数之前?因为在我的软件,如果放在其他地方,会出现两个运行程序,目前原因还不清楚。

2、cef初始化代码

bool CefManager::CefInit()
{
	HINSTANCE hInstance = ::GetModuleHandle(NULL);

	// Enable High-DPI support on Windows 7 or newer.
	CefEnableHighDPISupport();

	void* sandbox_info = NULL;

#if defined(CEF_USE_SANDBOX)
	// Manage the life span of the sandbox information object. This is necessary
	// for sandbox support on Windows. See cef_sandbox_win.h for complete details.
	CefScopedSandboxInfo scoped_sandbox;
	sandbox_info = scoped_sandbox.sandbox_info();
#endif

	// Provide CEF with command-line arguments.
	CefMainArgs main_args(hInstance);

	// CEF applications have multiple sub-processes (render, plugin, GPU, etc)
	// that share the same executable. This function checks the command-line and,
	// if this is a sub-process, executes the appropriate logic.
	int exit_code = CefExecuteProcess(main_args, NULL, sandbox_info);
	if (exit_code >= 0) {
		// The sub-process has completed so return here.
		return exit_code;
	}

	// Specify CEF global settings here.
	CefSettings settings;

#if !defined(CEF_USE_SANDBOX)
	settings.no_sandbox = true;
#endif
	settings.multi_threaded_message_loop = true;
	// SimpleApp implements application-level callbacks for the browser process.
	// It will create the first browser instance in OnContextInitialized() after
	// CEF has initialized.
	CefRefPtr<SimpleApp> app(new SimpleApp);

	// Initialize CEF.
	CefInitialize(main_args, settings, app.get(), sandbox_info);

	return true;
}

3、浏览器创建

bool QCefView::createCefBrowser()
{
	RECT rect;
	rect.left = 0;
	rect.top = 0;
	rect.right = qobject_cast<QWidget*>(this->parent())->width();
	rect.bottom = qobject_cast<QWidget*>(this->parent())->height();

	CefWindowInfo windowInfo;
	CefBrowserSettings browserSettings;

	windowInfo.SetAsChild(reinterpret_cast<HWND>(this->winId()), rect);
	CefBrowserHost::CreateBrowser(windowInfo, _browserHandler.get(),
		CefString(_url.toStdWString()), browserSettings, nullptr);

	qDebug() << "CreateBrowser success!" << _url;

	return true;
}

通过CreteBrowser()函数创建浏览器,CefWindowInfo对象的SetAsChild函数设置当前窗口的句柄ID为接下来浏览器的父窗口,从而实现内嵌CEF浏览器到Qt窗口中。

4、加载Url

void QCefView::loadUrl(const QString &url)
{
	if (url.isEmpty()) return;
	_url = url;
	qDebug() << "loadUrl" << _url;

	createCefBrowser();
}

这里直接传入QString字符串,然后调用创建浏览器的接口。

5、界面内嵌cef的父窗口

QtCef::QtCef(QWidget *parent)
    : QWidget(parent)
{
    ui.setupUi(this);

	qDebug() << "QtCef Init";
	QVBoxLayout * vlayout = new QVBoxLayout;
	vlayout->setSpacing(0);
	vlayout->setMargin(0);
	_cefView = new QCefView(this);
	vlayout->addWidget(_cefView);
	this->setLayout(vlayout);

	_cefView->loadUrl("http://www.baidu.com");
}

通过addwidget将搭载cef浏览器的qt窗口添加到我们需要显示的界面上。

四、完整代码和库:

这只是一个简单的演示demo,功能并不完善,大家可以自行在此基础上进行拓展和完善。

如果有需要功能完善的代码和库的同学可以关注我的微信公众号 回复 CEF浏览器 领取源码:

  • 11
    点赞
  • 49
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值