首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >应用退出时CEF崩溃(QT5+CEF3.2526)

应用退出时CEF崩溃(QT5+CEF3.2526)
EN

Stack Overflow用户
提问于 2016-08-02 17:10:35
回答 2查看 1.7K关注 0票数 2

这是一个非常简单的QT+CEF windows应用程序,请参阅https://github.com/GreatTux/CefMinGWQt

当我关闭主窗口时,CEF触发断点:我想我在这里失败了:

代码语言:javascript
复制
void CefBrowserMainParts::PostMainMessageLoopRun() {
....
#ifndef NDEBUG
// No CefBrowserContext instances should exist at this point.
DCHECK_EQ(0, CefBrowserContext::DebugObjCt);
#endif
}

我不知道释放浏览器资源的正确方法是什么,我在web上看了很多例子,几乎所有的例子都在我的Windows 7+vs2010环境中遇到了这个问题

我也试过了,但不起作用

代码语言:javascript
复制
void ClientHandler::OnBeforeClose(CefRefPtr<CefBrowser> browser) {
  if(m_browser.get())
    m_browser = NULL;

====跟踪===

代码语言:javascript
复制
libcef.dll!base::debug::BreakDebugger()  Line 21    C++
libcef.dll!logging::LogMessage::~LogMessage()  Line 604 C++
libcef.dll!CefBrowserMainParts::PostMainMessageLoopRun()  Line 189  C++
libcef.dll!content::BrowserMainLoop::ShutdownThreadsAndCleanUp()  Line 946 + 0x27 bytes C++
libcef.dll!content::BrowserMainRunnerImpl::Shutdown()  Line 293 C++
libcef.dll!CefMainDelegate::ShutdownBrowser()  Line 659 + 0x1b bytes    C++
libcef.dll!CefContext::FinalizeShutdown()  Line 462 C++
libcef.dll!CefContext::Shutdown()  Line 345 C++
libcef.dll!CefShutdown()  Line 171  C++
libcef.dll!cef_shutdown()  Line 192 C++
qtloop.exe!CefShutdown()  Line 180 + 0x8 bytes  C++
qtloop.exe!main(int argc=1, char * * argv=0x00375b90)  Line 35  C++
qtloop.exe!WinMain(HINSTANCE__ * __formal=0x00fe0000, HINSTANCE__ *    __formal=0x00fe0000, HINSTANCE__ * __formal=0x00fe0000, HINSTANCE__ * __formal=0x00fe0000)  Line 113 + 0xd bytes C++
qtloop.exe!__tmainCRTStartup()  Line 547 + 0x2c bytes   C
qtloop.exe!WinMainCRTStartup()  Line 371    C
EN

回答 2

Stack Overflow用户

发布于 2017-02-14 11:36:54

当您关闭主窗口时,Qt不会立即销毁它,因此cef浏览器不会发布。此时返回app.exec(),运行CefShowDown()并触发调试检查。

我也遇到过同样的问题。这是因为当你关闭Cef时,也有一些浏览器是不可用的

DCHECK_EQ(0,CefBrowserContext::DebugObjCt);

我阅读了这篇文章并阅读了cef close process的源代码。

https://github.com/fanfeilong/cefutil/blob/master/doc/CEF_Close.md

我解决了这个问题,关键是,当你打电话给

GetHost()->CloseBrowser(false)

在cef上嵌入父窗口的closeEvent并忽略第一个closeEvent

然后,如果允许用户关闭,cef将再次发送close到父根窗口。

代码语言:javascript
复制
void CefBrowserHostImpl::PlatformCloseWindow() {
  if (window_info_.window != NULL) {
    HWND frameWnd = GetAncestor(window_info_.window, GA_ROOT);
    PostMessage(frameWnd, WM_CLOSE, 0, 0);
  }
}

当你收到第二个关闭,你需要确保关闭窗口,并立即销毁cef嵌入的窗口。Cef需要WM_DESTROY事件来释放资源并调用OnBeforeClose。

票数 2
EN

Stack Overflow用户

发布于 2020-06-28 13:51:46

您需要钩子窗口关闭操作,并确保cef浏览器先关闭。

标准流程是(摘自cef注释,稍作修改):

代码语言:javascript
复制
//
// 1.  User clicks the window close button which sends a close notification to
//     the application's top-level window.
// 2.  Application's top-level window receives the close notification and:
//     A. Calls CefBrowserHost::CloseBrowser(false).
//     B. Cancels the window close.
// 3.  JavaScript 'onbeforeunload' handler executes and shows the close
//     confirmation dialog (which can be overridden via
//     CefJSDialogHandler::OnBeforeUnloadDialog()).
// 4.  User approves the close.
// 5.  JavaScript 'onunload' handler executes.
// 6.  Application's DoClose() handler is called. Application will:
//     A. Set a flag to indicate that the next close attempt will be allowed.
//     B. Return false.
// 7.  Sends an close notification to the application's top-level window.
// 8.  Application's top-level window receives the close notification and
//     allows the window to close based on the flag from #6B.
// 9.  Application's top-level window is destroyed.
// 10. Application's OnBeforeClose() handler is called and the browser object
//     is destroyed.
// 11. Application exits by calling CefQuitMessageLoop() if no other browsers
//     exist.
///

我写了一个名为QCefWidget的项目,它基于QT + CEF OSR。它有一个完美的退出逻辑。你可以参考它

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/38716266

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档