Unsolved QWebEngine in non-main thread of native application
-
Hi,
I am trying to embed and show QWebEngine in my otherwise non-QT application. I created a separate thread in which I do:
DWORD WINAPI thread_fn_for_web(LPVOID lpParameter) { int argc = 0; char **argv = NULL; QApplication qapp(argc, argv); //QtWebEngine::initialize(); ----- Did not need this for webpage to show QWebEngineView* view = new QWebEngineView(); /*some code to set parent window of "view" to be a native window(HWND)*/ view->load(QUrl("http://www.qt.io/")); view->show(); return qapp.exec(); }
It works fine the first time I show the QWebEngineView, but when I close it and attempt to re-show(using the same code) it, I run into a access violation which is in QWebEngineCore::ProfileAdapter::userResourceController(). The QT source code of this userResourceController() is rather simple:
UserResourceControllerHost *ProfileAdapter::userResourceController() { if (!m_userResourceController) m_userResourceController.reset(new UserResourceControllerHost); return m_userResourceController.data(); }
When killing the view(outside of the thread) I do:
view->deleteLater(); view = 0;
I think it's because the cleanup of either QWebEngineView or QApplication wasn't done right? But when I do the same thing with a regular QWidget, instead of QWebEngineView, there's no problem. I read in some other posts that the clean up of QWebEngineView is tied to the destructor of QCoreApplication, could this be related?
I also did a mock application in which QApplication and QWebEngineView were created in main thread, and that works fine regardless of how many times I kill/show it.
Could anyone shed some light on what exactly caused QWebEngineView to not clean up properly? Not being in main thread doesn't seem to cause any issue for regular QWidget.
Thanks in advance.
-
@SanZ said in QWebEngine in non-main thread of native application:
DWORD WINAPI thread_fn_for_web(LPVOID lpParameter)
{
int argc = 0;
char *argv = NULL;
QApplication qapp(argc, argv);
//QtWebEngine::initialize(); ----- Did not need this for webpage to show
QWebEngineView view = new QWebEngineView();
/some code to set parent window of "view" to be a native window(HWND)/
view->load(QUrl("http://www.qt.io/"));
view->show();
return qapp.exec();
}There is no need to allocate view on the heap, simply allocate it on the stack:
DWORD WINAPI thread_fn_for_web(LPVOID lpParameter) { int argc = 0; char **argv = NULL; QApplication qapp(argc, argv); //QtWebEngine::initialize(); ----- Did not need this for webpage to show QWebEngineView view; /*some code to set parent window of "view" to be a native window(HWND)*/ view.load(QUrl("http://www.qt.io/")); view.show(); return qapp.exec(); }
If, for some reason, you want to allocate on the heap then delete it again just after qapp.exec(); (of course you would need to rework that part a bit).
-
Thank you for the reply. Unfortunately having the view on stack did not make the issue go away. I will try deleting it after exec(). Would something like this be the proper way to do it:
int ret = qapp.exec(); view->deleteLater(); return ret;
Thanks again.
-
@SanZ Change
view->deleteLater();
todelete view;
-
@eyllanesc Thanks, that makes sense, I guess because the event loop has already terminated with exec() being finished.
However with this I am still getting the same issue in QWebEngineCore::ProfileAdapter::userResourceController().
I will try to see if I can replicate the issue in my simpler mock application...
-
@SanZ Just confirmed that the problematic behaviour occurs when the whole thing is put to another thread. In my mock application I had everything in main thread, now I changed to
HANDLE hThread = CreateThread(0, 0, thread_fn_for_web, 0, 0, 0);
this is the same way as I did with my original application, and now the mock application is failing with the same issue. Anybody has any insight? Thanks.