Qt
Internal/Contributor docs for the Qt SDK. <b>Note:</b> These are NOT official API docs; those are found <a href='https://doc.qt.io/'>here</a>.
Loading...
Searching...
No Matches
qquickitemgrabresult.cpp
Go to the documentation of this file.
1// Copyright (C) 2016 Jolla Ltd, author: <gunnar.sletta@jollamobile.com>
2// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
3
4#include <private/qtquickglobal_p.h>
6
8#include "qquickwindow.h"
9#include "qquickitem.h"
10#if QT_CONFIG(quick_shadereffect)
12#endif
13
14#include <QtQml/QQmlEngine>
15#include <QtQml/QQmlInfo>
16
17#include <private/qquickpixmap_p.h>
18#include <private/qquickitem_p.h>
19#include <private/qsgcontext_p.h>
20#include <private/qsgadaptationlayer_p.h>
21
22#include <QtCore/qpointer.h>
23
25
27
71
142QQuickItemGrabResult::QQuickItemGrabResult(QObject *parent)
144{
145}
146
154// ### Qt 7: remove and keep only QUrl overload
162{
163 Q_D(const QQuickItemGrabResult);
164 if (fileName.startsWith(QLatin1String("file:/")))
165 return saveToFile(QUrl(fileName));
166 return d->image.save(fileName);
167}
168
176bool QQuickItemGrabResult::saveToFile(const QUrl &filePath) const
177{
178 Q_D(const QQuickItemGrabResult);
179 if (!filePath.isLocalFile()) {
180 qWarning() << "saveToFile can only save to a file on the local filesystem";
181 return false;
182 }
183 return d->image.save(filePath.toLocalFile());
184}
185
186#if QT_VERSION < QT_VERSION_CHECK(6, 0, 0)
187#if QT_DEPRECATED_SINCE(5, 15)
193{
194 return std::as_const(*this).saveToFile(fileName);
195}
196#endif
197#endif // < Qt 6
198
200{
201 Q_D(const QQuickItemGrabResult);
202 d->ensureImageInCache();
203 return d->url;
204}
205
207{
208 Q_D(const QQuickItemGrabResult);
209 return d->image;
210}
211
216{
218 if (e->type() == Event_Grab_Completed) {
219 // JS callback
220 if (d->qmlEngine && d->callback.isCallable()) {
221 d->callback.call(QJSValueList() << d->qmlEngine->newQObject(this));
222 deleteLater();
223 } else {
224 Q_EMIT ready();
225 }
226 return true;
227 }
228 return QObject::event(e);
229}
230
231void QQuickItemGrabResult::setup()
232{
234 if (!d->item) {
235 disconnect(d->window.data(), &QQuickWindow::beforeSynchronizing, this, &QQuickItemGrabResult::setup);
236 disconnect(d->window.data(), &QQuickWindow::afterRendering, this, &QQuickItemGrabResult::render);
238 return;
239 }
240
241 QSGRenderContext *rc = QQuickWindowPrivate::get(d->window.data())->context;
242 d->devicePixelRatio = d->window->effectiveDevicePixelRatio();
243 d->texture = rc->sceneGraphContext()->createLayer(rc);
244 d->texture->setDevicePixelRatio(d->devicePixelRatio);
245 d->texture->setItem(QQuickItemPrivate::get(d->item)->itemNode());
246 d->itemSize = QSizeF(d->item->width(), d->item->height());
247}
248
249void QQuickItemGrabResult::render()
250{
252 if (!d->texture)
253 return;
254
255 d->texture->setRect(QRectF(0, d->itemSize.height(), d->itemSize.width(), -d->itemSize.height()));
256 const QSize minSize = QQuickWindowPrivate::get(d->window.data())->context->sceneGraphContext()->minimumFBOSize();
257 const QSize effectiveTextureSize = d->textureSize * d->devicePixelRatio;
258 d->texture->setSize(QSize(qMax(minSize.width(), effectiveTextureSize.width()),
259 qMax(minSize.height(), effectiveTextureSize.height())));
260 d->texture->scheduleUpdate();
261 d->texture->updateTexture();
262 d->image = d->texture->toImage();
263 d->image.setDevicePixelRatio(d->devicePixelRatio);
264
265 delete d->texture;
266 d->texture = nullptr;
267
268 disconnect(d->window.data(), &QQuickWindow::beforeSynchronizing, this, &QQuickItemGrabResult::setup);
269 disconnect(d->window.data(), &QQuickWindow::afterRendering, this, &QQuickItemGrabResult::render);
271}
272
274{
275 QSize size = targetSize;
276 if (size.isEmpty())
277 size = QSize(item->width(), item->height());
278
279 if (size.width() < 1 || size.height() < 1) {
280 qmlWarning(item) << "grabToImage: item has invalid dimensions";
281 return nullptr;
282 }
283
284 if (!item->window()) {
285 qmlWarning(item) << "grabToImage: item is not attached to a window";
286 return nullptr;
287 }
288
291 effectiveWindow = renderWindow;
292
293 if (!effectiveWindow->isVisible()) {
294 qmlWarning(item) << "grabToImage: item's window is not visible";
295 return nullptr;
296 }
297
300 d->item = item;
301 d->window = item->window();
302 d->textureSize = size;
303
304 QQuickItemPrivate::get(item)->refFromEffectItem(false);
305
306 // trigger sync & render
307 item->window()->update();
308
309 return result;
310}
311
330QSharedPointer<QQuickItemGrabResult> QQuickItem::grabToImage(const QSize &targetSize)
331{
333 if (!result)
334 return QSharedPointer<QQuickItemGrabResult>();
335
337 connect(window(), &QQuickWindow::afterRendering, result, &QQuickItemGrabResult::render, Qt::DirectConnection);
338
339 return QSharedPointer<QQuickItemGrabResult>(result);
340}
341
376bool QQuickItem::grabToImage(const QJSValue &callback, const QSize &targetSize)
377{
378 QQmlEngine *engine = qmlEngine(this);
379 if (!engine) {
380 qmlWarning(this) << "grabToImage: item has no QML engine";
381 return false;
382 }
383
384 if (!callback.isCallable()) {
385 qmlWarning(this) << "grabToImage: 'callback' is not a function";
386 return false;
387 }
388
390 if (size.isEmpty())
391 size = QSize(width(), height());
392
393 if (size.width() < 1 || size.height() < 1) {
394 qmlWarning(this) << "grabToImage: item has invalid dimensions";
395 return false;
396 }
397
398 if (!window()) {
399 qmlWarning(this) << "grabToImage: item is not attached to a window";
400 return false;
401 }
402
404 if (!result)
405 return false;
406
408 connect(window(), &QQuickWindow::afterRendering, result, &QQuickItemGrabResult::render, Qt::DirectConnection);
409
411 d->qmlEngine = engine;
412 d->callback = callback;
413 return true;
414}
415
417
418#include "moc_qquickitemgrabresult.cpp"
static void postEvent(QObject *receiver, QEvent *event, int priority=Qt::NormalEventPriority)
\inmodule QtCore
Definition qcoreevent.h:45
Type
This enum type defines the valid event types in Qt.
Definition qcoreevent.h:51
Type type() const
Returns the event type.
Definition qcoreevent.h:304
\inmodule QtGui
Definition qimage.h:37
The QJSValue class acts as a container for Qt/JavaScript data types.
Definition qjsvalue.h:31
bool isCallable() const
Returns true if this QJSValue is a function, otherwise returns false.
Definition qjsvalue.cpp:450
\inmodule QtCore
Definition qobject.h:103
static QMetaObject::Connection connect(const QObject *sender, const char *signal, const QObject *receiver, const char *member, Qt::ConnectionType=Qt::AutoConnection)
\threadsafe
Definition qobject.cpp:2960
virtual bool event(QEvent *event)
This virtual function receives events to an object and should return true if the event e was recogniz...
Definition qobject.cpp:1389
void deleteLater()
\threadsafe
Definition qobject.cpp:2435
T * data() const noexcept
Definition qpointer.h:73
The QQmlEngine class provides an environment for instantiating QML components.
Definition qqmlengine.h:57
QPointer< QQuickWindow > window
static QQuickItemGrabResult * create(QQuickItem *item, const QSize &size)
QUrl url
\qmlproperty url QtQuick::ItemGrabResult::url
void ready()
This signal is emitted when the grab has completed.
Q_INVOKABLE bool saveToFile(const QString &fileName) const
\qmlmethod bool QtQuick::ItemGrabResult::saveToFile(fileName)
QImage image
\qmlproperty variant QtQuick::ItemGrabResult::image
bool event(QEvent *) override
static QQuickItemPrivate * get(QQuickItem *item)
The QQuickItem class provides the most basic of all visual items in \l {Qt Quick}.
Definition qquickitem.h:63
QSharedPointer< QQuickItemGrabResult > grabToImage(const QSize &targetSize=QSize())
Grabs the item into an in-memory image.
QQuickWindow * window() const
Returns the window in which this item is rendered.
qreal width
This property holds the width of this item.
Definition qquickitem.h:75
const QSize & targetSize
Definition qquickitem.h:306
qreal height
This property holds the height of this item.
Definition qquickitem.h:76
static const QLatin1String itemGrabberScheme
static QWindow * renderWindowFor(QQuickWindow *win, QPoint *offset=nullptr)
Returns the real window that win is being rendered to, if any.
static QQuickWindowPrivate * get(QQuickWindow *c)
void beforeSynchronizing()
This signal is emitted before the scene graph is synchronized with the QML state.
void update()
Schedules the window to render another frame.
void afterRendering()
\qmlsignal QtQuick::Window::beforeRendering()
\inmodule QtCore\reentrant
Definition qrect.h:484
virtual QSGLayer * createLayer(QSGRenderContext *renderContext)=0
QSGContext * sceneGraphContext() const
\inmodule QtCore
Definition qsize.h:208
\inmodule QtCore
Definition qsize.h:25
constexpr int height() const noexcept
Returns the height.
Definition qsize.h:133
constexpr int width() const noexcept
Returns the width.
Definition qsize.h:130
\macro QT_RESTRICTED_CAST_FROM_ASCII
Definition qstring.h:129
static QString number(int, int base=10)
This is an overloaded member function, provided for convenience. It differs from the above function o...
Definition qstring.cpp:8084
\inmodule QtCore
Definition qurl.h:94
bool isLocalFile() const
Definition qurl.cpp:3445
void setFragment(const QString &fragment, ParsingMode mode=TolerantMode)
Sets the fragment of the URL to fragment.
Definition qurl.cpp:2648
bool isEmpty() const
Returns true if the URL has no data; otherwise returns false.
Definition qurl.cpp:1896
void setScheme(const QString &scheme)
Sets the scheme of the URL to scheme.
Definition qurl.cpp:1967
void setPath(const QString &path, ParsingMode mode=DecodedMode)
Sets the path of the URL to path.
Definition qurl.cpp:2414
QString toLocalFile() const
Returns the path of this URL formatted as a local file path.
Definition qurl.cpp:3425
static auto fromValue(T &&value) noexcept(std::is_nothrow_copy_constructible_v< T > &&Private::CanUseInternalSpace< T >) -> std::enable_if_t< std::conjunction_v< std::is_copy_constructible< T >, std::is_destructible< T > >, QVariant >
Definition qvariant.h:536
\inmodule QtGui
Definition qwindow.h:63
Combined button and popup list for selecting options.
@ DirectConnection
Definition image.cpp:4
QList< QJSValue > QJSValueList
Definition qjsvalue.h:22
#define qWarning
Definition qlogging.h:166
constexpr const T & qMax(const T &a, const T &b)
Definition qminmax.h:42
GLenum GLuint GLintptr GLsizeiptr size
[1]
GLenum GLuint texture
GLuint counter
GLuint64EXT * result
[6]
QQmlEngine * qmlEngine(const QObject *obj)
Definition qqml.cpp:80
Q_QML_EXPORT QQmlInfo qmlWarning(const QObject *me)
QT_BEGIN_NAMESPACE const QEvent::Type Event_Grab_Completed
static QWindow * effectiveWindow(QWindow *window, QPoint *offset)
#define Q_EMIT
unsigned int uint
Definition qtypes.h:34
double qreal
Definition qtypes.h:187
QObject::connect nullptr
myObject disconnect()
[26]
QGraphicsItem * item
view create()
QJSEngine engine
[0]