Example bellow can grab any qml content to FBO and then sent it as Image via signal. Only one problem of this approach is visibility, grab window must be visible for successful grabbing. If anybody knows how to prevent this you can help me and provide more advanced approach.
// main.cpp
int main(int argc, char* argv[])
{
QApplication app(argc, argv);
GrabWindow grab;
grab.setResizeMode( QQuickView::SizeViewToRootObject );
grab.setSource( QUrl::fromLocalFile("qml/main.qml") );
grab.setFlags( Qt::Popup );
grab.show();
return app.exec();
}
// grabwindow.hpp
#pragma once
#include <QOpenGLFramebufferObject>
#include <QScopedPointer>
#include <QQuickView>
#include <QImage>
class GrabWindow: public QQuickView
{
Q_OBJECT
signals:
void changeImage( const QImage &image );
public:
GrabWindow( QWindow * parent = 0 );
private slots:
void afterRendering();
void beforeRendering();
private:
QScopedPointer<QOpenGLFramebufferObject> fbo_;
};
// grabwindow.cpp
#include "grabwindow.hpp"
#include <limits>
GrabWindow::GrabWindow( QWindow * parent ) :
QQuickView( parent )
{
setClearBeforeRendering( false );
setPosition( std::numeric_limits<unsigned short>::max(), std::numeric_limits<unsigned short>::max() );
connect( this, SIGNAL( afterRendering() ), SLOT( afterRendering() ), Qt::DirectConnection );
connect( this, SIGNAL( beforeRendering() ), SLOT( beforeRendering() ), Qt::DirectConnection );
}
void GrabWindow::afterRendering()
{
if( !fbo_.isNull() )
{
emit changeImage( fbo_->toImage() );
}
}
void GrabWindow::beforeRendering()
{
if (!fbo_)
{
fbo_.reset(new QOpenGLFramebufferObject( size(), QOpenGLFramebufferObject::NoAttachment) );
setRenderTarget(fbo_.data());
}
}