编译libcef_dll_wrapper
因为Qt是动态库调用形式,所以需要将libcef_dll_wrapper属性的运行库设置位多线程 DLL (/MD),如果是debug设置多线程调试 DLL (/MDd),然后编译。我在使用debug版的时候出现了几个无法解决问题,所以我这里编译的是release版,什么问题在最后会阐述。
构建cef的qGUI工程
1)新建QBrowser界面工程
2)将cef的include文件夹拷贝到QBrowser工程下,设置属性-》C/C++->常规-》附加包含目录为include目录和include的上级目录
3)在QBrowser新建lib目录,将libcef_dll_wrapper.lib和libcef.lib考到lib目录下,设置属性-》连接器-》常规-》附加库目录为lib目录,添加属性-》链接器-》输入-》附加依赖项为libcef_dll_wrapper.lib和libcef.lib。
2)将cefsimple源文件拷到QBRoweser'工程源码目录下。
simple_app.h
simple_app.cc
simple_handler.h
simple_handler.cc
simple_handler_win.cc
3)修改QBrower的cpp文件
在QBrower.ui中添加windget,objectname为contantwidget。
#include "QBrowser.h"
#include "stdafx.h"
#include "simple_handler.h"
QBrowser::QBrowser(QWidget *parent)
: QWidget(parent)
{
ui.setupUi(this);
InitBrowser();
}
void QBrowser::InitBrowser()
{
QString strUrl = "www.baidu.com";
CefRefPtr<SimpleHandler> handler(new SimpleHandler(false));
CefRefPtr<SimpleHandler> m_browserEvent;= SimpleHandler::GetInstance();
HWND wnd = (HWND)this->ui.contentwidget->winId();
RECT winRect;
winRect.left = 0;
winRect.top = 0;
winRect.right = 800;
winRect.bottom = 800;
CefWindowInfo cefWndInfo;
cefWndInfo.SetAsChild(wnd, winRect);
CefBrowserSettings cefBrowSetting;
CefBrowserHost::CreateBrowser(cefWndInfo, handler, strUrl.toStdString(), cefBrowSetting, NULL,NULL);
}
4)修改main函数
#include "QBrowser.h"
#include "stdafx.h"
#include <QtWidgets/QApplication>
#include "main.h"
#include <include/cef_app.h>
#include "simple_handler.h"
#include "simple_app.h"
void QCefInitSettings(CefSettings & settings)
{
settings.multi_threaded_message_loop = true;//多线程消息循环
settings.log_severity = LOGSEVERITY_DISABLE;//日志
settings.windowless_rendering_enabled = true;
settings.no_sandbox = true;//沙盒
}
int CefInit()
{
HINSTANCE hInstance = static_cast<HINSTANCE>(GetModuleHandle(nullptr));
CefMainArgs mainArgs(hInstance);
CefRefPtr<SimpleApp> app(new SimpleApp); //CefApp实现,用于处理进程相关的回调。
void* sandbox_info = nullptr;
int exit_code = CefExecuteProcess(mainArgs, nullptr, nullptr);
if (exit_code >= 0) {
return exit_code;
}
CefSettings settings;
QCefInitSettings(settings);
CefInitialize(mainArgs, settings, app.get(), nullptr);
return -1;
}
void CefQuit()
{
CefShutdown();
}
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
int result = CefInit();
if (result >= 0) {
return result;
}
QBrowser w;
w.show();
a.exec();
CefQuit();
return 0;
}
5)编译。
编译失败,修改include路径后,再次编译,编译通过。
6)运行
a. 直接运行会崩溃到CefInitialize。需要将cef资源文件拷贝到exe目录下,下面列举拷贝资源:
D:\CEF\cef_binary_85.3.13+gcd6cbe0+chromium-85.0.4183.121_windows64\Resource目录下文件
D:\CEF\cef_binary_86.0.21+g6a2c8e7+chromium-86.0.4240.183_windows64\Release目录下文件(如果是debug请选择debug文件)
b.再次运行启动成功,但是会弹出两个框来,一个是qt框,一个是simple_app中弹的框。将simple_app中的弹窗代码注掉。
c.再次运行成功
遇到的问题
解决掉的问题
1. 不添加cef资源文件,启动会崩溃,已经解决。
2.会启动两个窗口,已经解决。
未解决的问题,希望哪位大神能够帮忙解决。
1.release版不出,debug版有问题,如果不将void SimpleApp::OnContextInitialized() 函数实现注掉,运行会崩溃。
2.release版不出,debug版启动后会白屏,百度中说添加在属性-》生成时间-》生成后事件中加添命令行能解决,但是也没有解决。
setlocal
mt.exe -nologo -manifest "D:/VSProject/QBrowser/x64/Debug/cefsimple.exe.manifest" "D:/VSProject/QBrowser/x64/Debug/compatibility.manifest" -outputresource:"D:/VSProject/QBrowser/x64/Debug/QBrowser.exe";#1
if %errorlevel% neq 0 goto :cmEnd
:cmEnd
endlocal & call :cmErrorLevel %errorlevel% & goto :cmDone
:cmErrorLevel
exit /b %1
:cmDone
if %errorlevel% neq 0 goto :VCEnd
但是添加这段代码后,去掉qt的事件循环,添加cef的事件循环,能够弹出simple_app中的框,否则连simpl'e_app中的框也不弹。下面是添加命令行后,修改mian方法后,弹cef框的代码
int main(int argc, char *argv[])
{
//QApplication a(argc, argv);
int result = CefInit();
if (result >= 0) {
return result;
}
//QBrowser w;
//w.show();
//a.exec();
CefRunMessageLoop();
CefQuit();
return 0;
}
3.release版不出,debug版推出崩溃,没有解决。
网上查找的原因:
原因一、库版本问题。相信大家在入CEF坑时就听说,CEF的坑比较多,最新的版本可能会有问题。那么好的,关闭崩溃的问题确实还是因为版本的问题(至少我崩溃是因为这个)。鄙人现在用的版本是3.2704.1431的版本。亲测64 位和32位都不会崩溃!之前是使用的官网下载的最新版本,表示真的会崩溃。
原因二、使用官网下载的release文件夹下的文件。libcef.lib、libcef.dll等等。鄙人猜测可能是release下代码优化了断言,以至于略过了崩溃问题,因为debug版本下的崩溃处就是在断言处!
原因三、在官网下载的例子中,都会有附赠的例子如:cefsimple。OnAfterCreated、DoClose、OnBeforeClose这三个函数不要乱改哦~肯定有好多人会像我一样,改成自己想要的简化类。就把一些东西修改或者删除了。我也有一部分原因是因为这类崩溃的。
上面未解决的问题可能使用旧版本cef能够避免,在此没有做过多尝试后面再做研究。希望哪位能够解决,能够帮助我。