前面一篇大概的介绍了QT + CEF3的环境搭建,下面开始讲CEF3嵌入Qt中。
1、将libcef_dll_wrapper编译方式设置为MD
Qt使用的lib库是动态链接的,而cef使用的是静态链接的方式,所以在将libcef_dll_wrapper改成动态链接。
在VS的C/C+±>Code Generation下的Runtime Library中将release的编译方式改成Multi-thread DLL(/MD),debug版本的编译方式改成Multi-thread Debug DLL(/MDd),重新编译即可。
2、新建QT GUI项目
为了快速实现,选择将cefsimple中的源码,嫁接到QtGUI中。
2.1 导入cefsimple
首先把cef目录下的include拷贝到新项目中,再将libcef_dll_wrapper.lib和libcef.dll拷贝到新项目的lib目录下。再将cefsimple中的simple_app.h、simple_app.cc、simple_handler.h、simple_handler.cc、simple_handler_win.cc拷贝到我们自己的项目源码目录下。
在工程上右击选择“添加库”,然后选择“外部库”,添加libcef.dll,导入即可。
或者直接在pro中编辑:
win32:CONFIG(release, debug|release): LIBS += -L$$PWD/lib/ -llibcef -llibcef_dll_wrapper
else:win32:CONFIG(debug, debug|release): LIBS += -L$$PWD/libd/ -llibcef -llibcef_dll_wrapper
else:unix: LIBS += -L$$PWD/lib/ -llibcef -llibcef_dll_wrapper
pro中直接添加:
INCLUDEPATH += $$PWD/include
DEPENDPATH += $$PWD/include
导入cef的include文件
修改Simple_app.cc、Simple_handler.cc、Simple_handler_win.cc文件中的头文件路径。
然后在Simple_app.cc中SimpleApp::OnContextInitialized()的开始添加位置添加return。
2.2 修改main.cpp
main.cpp中添加CefInit()和CefQuit()两个函数。
CefInit()函数:
bool CefInit()
{
CefEnableHighDPISupport();
void* sandbox_info = NULL;
#if defined(CEF_USE_SANDBOX)
CefScopedSandboxInfo scoped_sandbox;
sandbox_info = scoped_sandbox.sandbox_info();
#endif
HINSTANCE inc = GetModuleHandle(NULL);
CefMainArgs mainArgs(inc);
int exit_code = CefExecuteProcess(mainArgs, NULL, sandbox_info);
if (exit_code >= 0) {
// The sub-process has completed so return here.
return exit_code;
}
CefSettings settings;
settings.multi_threaded_message_loop = true;
#if !defined(CEF_USE_SANDBOX)
settings.no_sandbox = true;
#endif
CefRefPtr<SimpleApp> app(new SimpleApp);
return CefInitialize(mainArgs, settings, app.get(), sandbox_info);
}
CefQuit()函数:
void CefQuit()
{
CefShutdown();
}
并在main函数中添加CefInit()和CefQuit()的调用。
QApplication a(argc, argv);
CefInit();
Widget w;
w.show();
int ret = a.exec();
CefQuit();
return ret;
此处在a.exec()后调用CefQuit()会有个问题,QT窗口关闭后,会重新打开一个窗口,等一会会自行关闭。如果不想打开这个窗口,则需要重写exec()函数,在exec()中调用CefShutdown()。
2.3 添加cef3窗口
widget.cpp中添加InitBrowser()函数,加载cef窗口。
代码如下:
CefWindowInfo cefWndInfo;
QString strUrl = "https://weibo.com";
HWND wnd = (HWND)ui->widget->winId();
RECT winRect;
QRect qtRect = ui->widget->rect();
winRect.left = qtRect.left();
winRect.top = qtRect.top();
winRect.right = qtRect.right();
winRect.bottom = qtRect.bottom();
cefWndInfo.SetAsChild(wnd, winRect); //将cef界面嵌入qt界面中
CefBrowserSettings cefBrowSetting;
CefRefPtr<SimpleHandler> m_browserEvent = CefRefPtr<SimpleHandler>(new SimpleHandler(true));
bool browser = CefBrowserHost::CreateBrowser(cefWndInfo, m_browserEvent, strUrl.toStdString(), cefBrowSetting, NULL,NULL);
不要忘记在构造函数中调用,第一次启动成功时,一直白屏,找了很久,才发现忘记调用该函数加载cef画面了。
这时,QT中嵌入cef3基本上算是完成了。
此时直接使用QT默认的MinGW编译器编译会出现很多error,需要使用MSVC2015或MSVC2017编译器。
启动后,等待一会就可以显示网页了。
忘了说了,第一次启动,可能会崩溃,需要将cefsimple的debug或release文件夹中除cefsimple.exe、cefsimple.exp和cefsimple.lib三个文件外的其他文件,都拷贝到编译的工程目录下。