Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • Users
  • Groups
  • Search
  • Get Qt Extensions
  • Unsolved
Collapse
Brand Logo
  1. Home
  2. Qt Development
  3. General and Desktop
  4. QWebEngine in non-main thread of native application

QWebEngine in non-main thread of native application

Scheduled Pinned Locked Moved Unsolved General and Desktop
6 Posts 3 Posters 683 Views
  • Oldest to Newest
  • Newest to Oldest
  • Most Votes
Reply
  • Reply as topic
Log in to reply
This topic has been deleted. Only users with topic management privileges can see it.
  • S Offline
    S Offline
    SanZ
    wrote on last edited by
    #1

    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.

    jsulmJ 1 Reply Last reply
    0
    • S SanZ

      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.

      jsulmJ Offline
      jsulmJ Offline
      jsulm
      Lifetime Qt Champion
      wrote on last edited by
      #2

      @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).

      https://forum.qt.io/topic/113070/qt-code-of-conduct

      1 Reply Last reply
      0
      • S Offline
        S Offline
        SanZ
        wrote on last edited by
        #3

        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.

        eyllanescE 1 Reply Last reply
        0
        • S SanZ

          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.

          eyllanescE Offline
          eyllanescE Offline
          eyllanesc
          wrote on last edited by
          #4

          @SanZ Change view->deleteLater(); to delete view;

          If you want me to help you develop some work then you can write to my email: e.yllanescucho@gmal.com.

          S 1 Reply Last reply
          0
          • eyllanescE eyllanesc

            @SanZ Change view->deleteLater(); to delete view;

            S Offline
            S Offline
            SanZ
            wrote on last edited by
            #5

            @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...

            S 1 Reply Last reply
            0
            • S SanZ

              @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...

              S Offline
              S Offline
              SanZ
              wrote on last edited by
              #6

              @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.

              1 Reply Last reply
              0

              • Login

              • Login or register to search.
              • First post
                Last post
              0
              • Categories
              • Recent
              • Tags
              • Popular
              • Users
              • Groups
              • Search
              • Get Qt Extensions
              • Unsolved