QWebEngine:删除 QWebEngineUrlRequestInterceptor 导致崩溃
QWebEngine: deleting QWebEngineUrlRequestInterceptor results in crash
在我的项目中,我想 create/delete QWebEnginePages
当 opening/closing 一个应用程序。使用 Qt5.9.7
一切正常。切换到 Qt5.12.6
时,我的应用程序会崩溃。
我创建了一个小代码示例,我只需单击一个按钮即可创建和删除。当然,在我的真实项目中,我确保一切都受到保护等:
BrowserWidget::BrowserWidget(QWidget *parent)
: QWidget(parent), ui(new Ui::Widget) {
m_webView = new QWebEngineView(this);
ui->setupUi(this);
ui->verticalLayout->addWidget(m_webView);
connect(ui->createBtn, &QPushButton::clicked, this,
&BrowserWidget::createSession);
connect(ui->deleteBtn, &QPushButton::clicked, this,
&BrowserWidget::deleteSession);
}
BrowserWidget::~BrowserWidget() {
delete ui;
}
void BrowserWidget::createSession() {
m_page = new QWebEnginePage(this);
m_interceptor = new UrlRequestInterceptor(this);
m_page->profile()->setRequestInterceptor(m_interceptor);
for (auto c : m_connections) {
disconnect(c);
}
m_connections.clear();
m_page->setUrl(
QUrl(QStringLiteral("https://www.youtube.com/watch?v=rNSnfXl1ZjU")));
m_webView->setPage(m_page);
return;
}
void BrowserWidget::deleteSession() {
delete m_page;
delete m_interceptor; // This causes the crash
}
整个UrlRequestInterceptor.cpp看起来像这样:
UrlRequestInterceptor::UrlRequestInterceptor(QObject *parent)
: QWebEngineUrlRequestInterceptor(parent) {}
void UrlRequestInterceptor::interceptRequest(QWebEngineUrlRequestInfo &info) {
info.block(false);
return;
}
当我快速打开和关闭 "WebPages" 时,delete m_interceptor
会导致崩溃。当网页完全加载时,有时也会发生这种情况,但并不经常发生。
我在文档中找不到任何相关信息。
你们中有人知道我如何才能可靠地等待所有 interceptor/browser-related 内容完成后再删除 m_interceptor
吗?
这是有用的堆栈跟踪:
1 QtWebEngineCore::CustomProtocolHandler::MaybeCreateJob Qt5WebEngineCored 0x7ffd06bdd708
2 QtWebEngineCore::CookieMonsterDelegateQt::hasCookieMonster Qt5WebEngineCored 0x7ffd0a4aa0ae
3 QtWebEngineCore::CookieMonsterDelegateQt::hasCookieMonster Qt5WebEngineCored 0x7ffd0a4b1ca5
4 QtWebEngineCore::WebContentsAdapter::webContents Qt5WebEngineCored 0x7ffd094b5a12
5 QtWebEngineCore::WebContentsAdapter::webContents Qt5WebEngineCored 0x7ffd094b4a01
6 QtWebEngineCore::WebContentsAdapter::webContents Qt5WebEngineCored 0x7ffd094b0769
7 QtWebEngineCore::WebContentsAdapter::webContents Qt5WebEngineCored 0x7ffd094b5777
8 QtWebEngineCore::WebContentsAdapter::webContents Qt5WebEngineCored 0x7ffd094a83c8
9 QtWebEngineCore::WebContentsAdapter::webContents Qt5WebEngineCored 0x7ffd094a078f
10 QtWebEngineCore::WebContentsAdapter::webContents Qt5WebEngineCored 0x7ffd094a34ca
11 QtWebEngineCore::WebContentsAdapter::webContents Qt5WebEngineCored 0x7ffd0949ffdf
12 QtWebEngineCore::WebContentsAdapter::webContents Qt5WebEngineCored 0x7ffd094a65c5
13 QtWebEngineCore::WebContentsAdapter::webContents Qt5WebEngineCored 0x7ffd094a67af
14 QtWebEngineCore::WebContentsAdapter::webContents Qt5WebEngineCored 0x7ffd094c15d3
15 QWebEngineCookieStorePrivate::q_func Qt5WebEngineCored 0x7ffd0b93f07d
16 QtWebEngineCore::WebContentsAdapter::webContents Qt5WebEngineCored 0x7ffd094b91bb
17 QtWebEngineCore::JavaScriptDialogController::qt_static_metacall Qt5WebEngineCored 0x7ffd06db6c45
18 QWebEngineQuotaRequest::QWebEngineQuotaRequest Qt5WebEngineCored 0x7ffd08ea7a85
19 QtWebEngineCore::FilePickerController::mode Qt5WebEngineCored 0x7ffd0a1c5e75
20 QtWebEngineCore::FilePickerController::mode Qt5WebEngineCored 0x7ffd0a1c4a31
非常感谢!
我认为您真的不需要在每次启动会话时都创建一个新的拦截器实例。在你的 BrowserWidget
class:
中只有一个实例
private:
Ui::BrowserWidget *ui;
UrlRequestInterceptor m_interceptor;
在小部件构造函数中初始化它:
BrowserWidget::BrowserWidget(QWidget *parent)
: QWidget(parent), ui(new Ui::BrowserWidget), m_interceptor(this)
将指向它的指针传递给页面配置文件:
void BrowserWidget::createSession() {
m_page = new QWebEnginePage(this);
m_page->profile()->setRequestInterceptor(&m_interceptor);
去掉deleteSession
中的delete
:
void BrowserWidget::deleteSession() {
delete m_page;
// delete m_interceptor; // This (no more) causes the crash
}
在我的项目中,我想 create/delete QWebEnginePages
当 opening/closing 一个应用程序。使用 Qt5.9.7
一切正常。切换到 Qt5.12.6
时,我的应用程序会崩溃。
我创建了一个小代码示例,我只需单击一个按钮即可创建和删除。当然,在我的真实项目中,我确保一切都受到保护等:
BrowserWidget::BrowserWidget(QWidget *parent)
: QWidget(parent), ui(new Ui::Widget) {
m_webView = new QWebEngineView(this);
ui->setupUi(this);
ui->verticalLayout->addWidget(m_webView);
connect(ui->createBtn, &QPushButton::clicked, this,
&BrowserWidget::createSession);
connect(ui->deleteBtn, &QPushButton::clicked, this,
&BrowserWidget::deleteSession);
}
BrowserWidget::~BrowserWidget() {
delete ui;
}
void BrowserWidget::createSession() {
m_page = new QWebEnginePage(this);
m_interceptor = new UrlRequestInterceptor(this);
m_page->profile()->setRequestInterceptor(m_interceptor);
for (auto c : m_connections) {
disconnect(c);
}
m_connections.clear();
m_page->setUrl(
QUrl(QStringLiteral("https://www.youtube.com/watch?v=rNSnfXl1ZjU")));
m_webView->setPage(m_page);
return;
}
void BrowserWidget::deleteSession() {
delete m_page;
delete m_interceptor; // This causes the crash
}
整个UrlRequestInterceptor.cpp看起来像这样:
UrlRequestInterceptor::UrlRequestInterceptor(QObject *parent)
: QWebEngineUrlRequestInterceptor(parent) {}
void UrlRequestInterceptor::interceptRequest(QWebEngineUrlRequestInfo &info) {
info.block(false);
return;
}
当我快速打开和关闭 "WebPages" 时,delete m_interceptor
会导致崩溃。当网页完全加载时,有时也会发生这种情况,但并不经常发生。
我在文档中找不到任何相关信息。
你们中有人知道我如何才能可靠地等待所有 interceptor/browser-related 内容完成后再删除 m_interceptor
吗?
这是有用的堆栈跟踪:
1 QtWebEngineCore::CustomProtocolHandler::MaybeCreateJob Qt5WebEngineCored 0x7ffd06bdd708
2 QtWebEngineCore::CookieMonsterDelegateQt::hasCookieMonster Qt5WebEngineCored 0x7ffd0a4aa0ae
3 QtWebEngineCore::CookieMonsterDelegateQt::hasCookieMonster Qt5WebEngineCored 0x7ffd0a4b1ca5
4 QtWebEngineCore::WebContentsAdapter::webContents Qt5WebEngineCored 0x7ffd094b5a12
5 QtWebEngineCore::WebContentsAdapter::webContents Qt5WebEngineCored 0x7ffd094b4a01
6 QtWebEngineCore::WebContentsAdapter::webContents Qt5WebEngineCored 0x7ffd094b0769
7 QtWebEngineCore::WebContentsAdapter::webContents Qt5WebEngineCored 0x7ffd094b5777
8 QtWebEngineCore::WebContentsAdapter::webContents Qt5WebEngineCored 0x7ffd094a83c8
9 QtWebEngineCore::WebContentsAdapter::webContents Qt5WebEngineCored 0x7ffd094a078f
10 QtWebEngineCore::WebContentsAdapter::webContents Qt5WebEngineCored 0x7ffd094a34ca
11 QtWebEngineCore::WebContentsAdapter::webContents Qt5WebEngineCored 0x7ffd0949ffdf
12 QtWebEngineCore::WebContentsAdapter::webContents Qt5WebEngineCored 0x7ffd094a65c5
13 QtWebEngineCore::WebContentsAdapter::webContents Qt5WebEngineCored 0x7ffd094a67af
14 QtWebEngineCore::WebContentsAdapter::webContents Qt5WebEngineCored 0x7ffd094c15d3
15 QWebEngineCookieStorePrivate::q_func Qt5WebEngineCored 0x7ffd0b93f07d
16 QtWebEngineCore::WebContentsAdapter::webContents Qt5WebEngineCored 0x7ffd094b91bb
17 QtWebEngineCore::JavaScriptDialogController::qt_static_metacall Qt5WebEngineCored 0x7ffd06db6c45
18 QWebEngineQuotaRequest::QWebEngineQuotaRequest Qt5WebEngineCored 0x7ffd08ea7a85
19 QtWebEngineCore::FilePickerController::mode Qt5WebEngineCored 0x7ffd0a1c5e75
20 QtWebEngineCore::FilePickerController::mode Qt5WebEngineCored 0x7ffd0a1c4a31
非常感谢!
我认为您真的不需要在每次启动会话时都创建一个新的拦截器实例。在你的 BrowserWidget
class:
private:
Ui::BrowserWidget *ui;
UrlRequestInterceptor m_interceptor;
在小部件构造函数中初始化它:
BrowserWidget::BrowserWidget(QWidget *parent)
: QWidget(parent), ui(new Ui::BrowserWidget), m_interceptor(this)
将指向它的指针传递给页面配置文件:
void BrowserWidget::createSession() {
m_page = new QWebEnginePage(this);
m_page->profile()->setRequestInterceptor(&m_interceptor);
去掉deleteSession
中的delete
:
void BrowserWidget::deleteSession() {
delete m_page;
// delete m_interceptor; // This (no more) causes the crash
}