qt5qtwebengineqwebengineviewqwebenginepage

Is it possible to render QWebEnginePage/QWebEngineView offscreen?


I have this partially working, but I'm facing several difficulties:

1) It appears that QWebEnginePage requires a QWebEngineView. (see setView() method here: https://code.woboq.org/qt5/qtwebengine/src/webenginewidgets/api/qwebenginepage.cpp.html)

2) QWebEngineView does not appear to render unless it's visible.

3) There don't appear to be any means to detect what areas of the view have been affected.

I'd like confirmation as to whether this is even possible to do with the new API? The old QT WebKit API offered a means to do this.


Solution

  • Yes, it's possible,

    Scene = std::make_unique<QGraphicsScene>();
    HiddenView = std::make_unique<QGraphicsView>(mScene.get());
    
    WebView = std::make_unique<QWebEngineView>();
    Scene->addWidget(mWebView.get());
    
    WebView->resize(size); //any QSize you like
    WebView->load(url); // give your url here
    
    mWebView->show(); //this doesn't actually show, just enables you to render offscreen, see below
    
    ImageData = QImage(size, QImage::Format_ARGB32);
    
    connect(mWebView.get(), &QWebEngineView::loadFinished, this, &ClassA::onViewLoaded);
    

    Then, in onViewLoaded we call an update() method to render in regular intervals. Note that 'this' is an object of ClassA.

    void ClassA::onViewLoaded(){
            Timer = std::make_unique<QTimer>();
            connect(mTimer.get(), &QTimer::timeout, , &SpaOffscreenRender::update);
            mTimer->start(30); //every 30 miliseconds
        }
    

    And finally you render like this:

    void ClassA::update()
    {
        QPainter painter(&ImageData);
        WebView->page()->view()->render(&painter);
        painter.end();
    }
    

    ImageData has what you want :)