12.12.2017, 16:13, "Denis Shienkov" <denis.shien...@gmail.com>: > Hi all... > > Is it possible to grab a QQuickItem content (e.g. with all sub-items) > when an item changes?
Did you try QQuickItem::grabToImage? > > E.g. with widgets I use the following code: > > bool MyWidget::event(QEvent *event) > { > if (event->type() == QEvent::UpdateRequest) > myGrab(); > return QWidget::event(event); > } > > void MyWidget::myGrab() > { > ... > QBackingStore *store = backingStore(); > Q_ASSERT(store); > > QPaintDevice *pdev = store->paintDevice(); > const auto image = dynamic_cast<QImage *>(pdev); > ... > } > > it is very fast (as I know)... > > But with the QML I got a troubles: I can 'grab' the sourceItem, using > the FBO and private functions, but the fbo::toImage() is too slow (~24 > msecs), > and I don't know how to intercept the signal when a watched item updates: > > Grabber::Grabber(QQuickItem *parent) > : QQuickItem(parent) > { > setFlag(QQuickItem::ItemHasContents); > } > > // Where sourceItem - is a watched item. > void Grabber::setSourceItem(QQuickItem *sourceItem) > { > if (sourceItem == m_sourceItem) > return; > m_sourceItem = sourceItem; > emit sourceItemChanged(m_sourceItem); > update(); > } > > QSGNode *Grabber::updatePaintNode(QSGNode *oldNode, > UpdatePaintNodeData *updatePaintNodeData) > { > Q_UNUSED(updatePaintNodeData); > > if (!m_sourceItem) > return oldNode; > > QSGRootNode root; > root.appendChildNode(QQuickItemPrivate::get(m_sourceItem)->itemNode()); > > const QScopedPointer<QSGRenderer> renderer( > QQuickItemPrivate::get(this)-> > sceneGraphRenderContext()->createRenderer()); > > renderer->setRootNode(&root); > > const QSize size(m_sourceItem->width(), m_sourceItem->height()); > renderer->setDeviceRect(size); > renderer->setViewportRect(size); > renderer->setProjectionMatrixToRect(QRectF(QPointF(), size)); > renderer->setClearColor(Qt::transparent); > > QOpenGLFramebufferObject fbo(size); > renderer->renderScene(BindableFbo(&fbo)); > fbo.release(); > > QElapsedTimer et; > et.start(); > const QImage image = fbo.toImage(); // TOO LONG ~24 msec! > qDebug() << "Elapsed:" << et.elapsed(); > > return oldNode; > } > > it is very fast (as I know). > > But with the QML I got a troubles: I can 'grub' an item, using the FBO, > > but the toImage() method is too slow (~24 msecs), and I don't know how > > to intercept a signal when the watched item updates: > > Grabber::Grabber(QQuickItem *parent) > : QQuickItem(parent) > { > setFlag(QQuickItem::ItemHasContents); > } > > QSGNode *Grabber::updatePaintNode(QSGNode *oldNode, > UpdatePaintNodeData *updatePaintNodeData) > { > Q_UNUSED(updatePaintNodeData); > > if (!m_sourceItem) > return oldNode; > > QSGRootNode root; > root.appendChildNode(QQuickItemPrivate::get(m_sourceItem)->itemNode()); > > const QScopedPointer<QSGRenderer> renderer( > QQuickItemPrivate::get(this)-> > sceneGraphRenderContext()->createRenderer()); > > renderer->setRootNode(&root); > > const QSize size(m_sourceItem->width(), m_sourceItem->height()); > renderer->setDeviceRect(size); > renderer->setViewportRect(size); > renderer->setProjectionMatrixToRect(QRectF(QPointF(), size)); > renderer->setClearColor(Qt::transparent); > > QOpenGLFramebufferObject fbo(size); > renderer->renderScene(BindableFbo(&fbo)); > fbo.release(); > > QElapsedTimer et; > et.start(); > const QImage image = fbo.toImage(); // TOO LONG! > qDebug() << "Elapsed:" << et.elapsed(); > > return oldNode; > } > > _______________________________________________ > Development mailing list > Development@qt-project.org > http://lists.qt-project.org/mailman/listinfo/development -- Regards, Konstantin _______________________________________________ Development mailing list Development@qt-project.org http://lists.qt-project.org/mailman/listinfo/development