Russian Qt Forum

Qt => Qt Quick => Тема начата: kuzulis от Февраль 08, 2017, 10:52



Название: [QML] Отловить момент обновления вьюхи и получить pixmap
Отправлено: kuzulis от Февраль 08, 2017, 10:52
Всем привет.

Возникла задача "грабить" вьюху приложения на QML.

В старом добром, теплом, ламповом, растровом Qt с плюсами для этого достаточно
было переопределить метод paintEvent() и делай что хочешь - и оно не тормозило.

Но в QML ничего не работает или оно тормозит жутко, т.к. надо грабить фреймы быстро.

Я знаю что:

1) есть QQuickWindow::grabWindow (http://doc.qt.io/qt-5/qquickwindow.html#grabWindow) метод,
   но он не подходит, т.к. медленный.

2) есть QQuickItem::grabToImage (http://doc.qt.io/qt-5/qquickitem.html#grabToImage) метод,
   но он не подходит, т.к. через некоторое время начинают приходить нулевые имиджи, и чем большее
   разрешение мы грабим, тем быстрее оно перестает слать имиджы. Да и медленно также.

3) для определения факта того, что вьюха перерисовалась я использовал сигнал
   QQuickWindow::afterRendering (http://doc.qt.io/qt-5/qquickwindow.html#afterRendering),
   но оно вызывается из потока рендера, и, может по этой причине останавливаются имиджы
   из п.2. Да и медленно также.

Может кто сталкивался, можно ли быстро отловить момент "перерисовки" вьюхи с быстренько
сграбить его картинку при использовании QML? А то прямо беда-печаль какая-то.

Было бы очень здорово, если бы, к примеру можно было бы получать только изменившийся
рект, а не рект всей вьюхи (например, как могет QGraphicsScene делать более менее).


Название: Re: [QML] Отловить момент обновления вьюхи и получить pixmap
Отправлено: Отражение луны от Февраль 08, 2017, 23:18
Не силен в cpp, но насколько мне известно это делается через фреймбуффер. Полагаю,
http://doc.qt.io/qt-5/qquickwindow.html#renderTarget
http://doc.qt.io/qt-5/qopenglframebufferobject.html#toImage
Не претендую на оригинальность и работоспособность совета, надеюсь, это как-то поможет.


Название: Re: [QML] Отловить момент обновления вьюхи и получить pixmap
Отправлено: kuzulis от Февраль 09, 2017, 09:46
Не, это уже испробовано. Я забыл упомянуть об этом.

Суть в том, что по умолчанию renderTarget() пуст (нулевой указатель), а внутри вся отрисовка ведется по умолчанию в окно.
Но если мы установим свой таргет через setRenderTarget(QOpenGLFramebufferObject *obj), то, да - оно будет рисоваться..
но не в окно а в тот заданый объект. Само же окно будет черным. Вот если бы можно было "распараллелить" отрисовку и
туда и сюда...