5#include <private/qtquickglobal_p.h>
11#if QT_CONFIG(quick_shadereffect)
12#include "qquickshadereffectsource_p.h"
15#include <QtQml/QQmlEngine>
16#include <QtQml/QQmlInfo>
18#include <private/qquickpixmap_p.h>
19#include <private/qquickitem_p.h>
20#include <private/qsgcontext_p.h>
21#include <private/qsgadaptationlayer_p.h>
23#include <QtCore/qpointer.h>
46 if (url.isEmpty() && !image.isNull()) {
47 url.setScheme(QQuickPixmap::itemGrabberScheme);
48 url.setPath(QVariant::fromValue(item.data()).toString());
49 static uint counter = 0;
50 url.setFragment(QString::number(++counter));
51 cacheEntry =
new QQuickPixmap(url, image);
55 static QQuickItemGrabResult *
create(QQuickItem *item,
const QSize &size);
74
75
76
77
78
79
80
81
82
83
84
85
88
89
90
91
92
93
94
95
96
97
100
101
102
103
104
107
108
109
110
111
112
113
116
117
118
119
120
121
124
125
126
127
130
131
132
133
134
135
136
137
138
139
140
141
143QQuickItemGrabResult::QQuickItemGrabResult(QObject *parent)
144 : QObject(*
new QQuickItemGrabResultPrivate, parent)
149
150
151
152
153
157
158
159
160
161
162bool QQuickItemGrabResult::saveToFile(
const QString &fileName)
const
164 Q_D(
const QQuickItemGrabResult);
165 if (fileName.startsWith(QLatin1String(
"file:/")))
166 return saveToFile(QUrl(fileName));
167 return d->image.save(fileName);
171
172
173
174
175
176
177bool QQuickItemGrabResult::saveToFile(
const QUrl &filePath)
const
179 Q_D(
const QQuickItemGrabResult);
180 if (!filePath.isLocalFile()) {
181 qWarning() <<
"saveToFile can only save to a file on the local filesystem";
184 return d->image.save(filePath.toLocalFile());
187#if QT_VERSION < QT_VERSION_CHECK(6
, 0
, 0
)
188#if QT_DEPRECATED_SINCE(5
, 15
)
190
191
192
193bool QQuickItemGrabResult::saveToFile(
const QString &fileName)
195 return std::as_const(*
this).saveToFile(fileName);
200QUrl QQuickItemGrabResult::url()
const
202 Q_D(
const QQuickItemGrabResult);
203 d->ensureImageInCache();
207QImage QQuickItemGrabResult::image()
const
209 Q_D(
const QQuickItemGrabResult);
214
215
216bool QQuickItemGrabResult::event(QEvent *e)
218 Q_D(QQuickItemGrabResult);
219 if (e->type() == Event_Grab_Completed) {
221 if (d->qmlEngine && d->callback.isCallable()) {
222 d->callback.call(QJSValueList() << d->qmlEngine->newQObject(
this));
223 QQmlEngine::setObjectOwnership(
this, QQmlEngine::JavaScriptOwnership);
229 return QObject::event(e);
232void QQuickItemGrabResult::setup()
234 Q_D(QQuickItemGrabResult);
236 disconnect(d->window.data(), &QQuickWindow::beforeSynchronizing,
this, &QQuickItemGrabResult::setup);
237 disconnect(d->window.data(), &QQuickWindow::afterRendering,
this, &QQuickItemGrabResult::render);
238 QCoreApplication::postEvent(
this,
new QEvent(Event_Grab_Completed));
242 QSGRenderContext *rc = QQuickWindowPrivate::get(d->window.data())->context;
243 d->devicePixelRatio = d->window->effectiveDevicePixelRatio();
244 d->texture = rc->sceneGraphContext()->createLayer(rc);
245 d->texture->setDevicePixelRatio(d->devicePixelRatio);
246 d->texture->setItem(QQuickItemPrivate::get(d->item)->itemNode());
247 d->itemSize = QSizeF(d->item->width(), d->item->height());
250void QQuickItemGrabResult::render()
252 Q_D(QQuickItemGrabResult);
256 d->texture->setRect(QRectF(0, d->itemSize.height(), d->itemSize.width(), -d->itemSize.height()));
257 const QSize minSize = QQuickWindowPrivate::get(d->window.data())->context->sceneGraphContext()->minimumFBOSize();
258 const QSize effectiveTextureSize = d->textureSize * d->devicePixelRatio;
259 d->texture->setSize(QSize(qMax(minSize.width(), effectiveTextureSize.width()),
260 qMax(minSize.height(), effectiveTextureSize.height())));
261 d->texture->scheduleUpdate();
262 d->texture->updateTexture();
263 d->image = d->texture->toImage();
264 d->image.setDevicePixelRatio(d->devicePixelRatio);
267 d->texture =
nullptr;
269 disconnect(d->window.data(), &QQuickWindow::beforeSynchronizing,
this, &QQuickItemGrabResult::setup);
270 disconnect(d->window.data(), &QQuickWindow::afterRendering,
this, &QQuickItemGrabResult::render);
271 QCoreApplication::postEvent(
this,
new QEvent(Event_Grab_Completed));
276 QSize size = targetSize;
278 size = QSize(item->width(), item->height());
280 if (size.width() < 1 || size.height() < 1) {
281 qmlWarning(item) <<
"grabToImage: item has invalid dimensions";
285 if (!item->window()) {
286 qmlWarning(item) <<
"grabToImage: item is not attached to a window";
290 QWindow *effectiveWindow = item->window();
291 if (QWindow *renderWindow = QQuickRenderControl::renderWindowFor(item->window()))
292 effectiveWindow = renderWindow;
294 if (!effectiveWindow->isVisible()) {
295 qmlWarning(item) <<
"grabToImage: item's window is not visible";
299 QQuickItemGrabResult *result =
new QQuickItemGrabResult();
302 d->window = item->window();
303 d->textureSize = size;
305 QQuickItemPrivate::get(item)->refFromEffectItem(
false);
308 item->window()->update();
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331QSharedPointer<QQuickItemGrabResult> QQuickItem::grabToImage(
const QSize &targetSize)
333 QQuickItemGrabResult *result = QQuickItemGrabResultPrivate::create(
this, targetSize);
335 return QSharedPointer<QQuickItemGrabResult>();
337 connect(window(), &QQuickWindow::beforeSynchronizing, result, &QQuickItemGrabResult::setup, Qt::DirectConnection);
338 connect(window(), &QQuickWindow::afterRendering, result, &QQuickItemGrabResult::render, Qt::DirectConnection);
340 return QSharedPointer<QQuickItemGrabResult>(result);
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
374
375
376
377bool QQuickItem::grabToImage(
const QJSValue &callback,
const QSize &targetSize)
379 QQmlEngine *engine = qmlEngine(
this);
381 qmlWarning(
this) <<
"grabToImage: item has no QML engine";
385 if (!callback.isCallable()) {
386 qmlWarning(
this) <<
"grabToImage: 'callback' is not a function";
390 QSize size = targetSize;
392 size = QSize(width(), height());
394 if (size.width() < 1 || size.height() < 1) {
395 qmlWarning(
this) <<
"grabToImage: item has invalid dimensions";
400 qmlWarning(
this) <<
"grabToImage: item is not attached to a window";
404 QQuickItemGrabResult *result = QQuickItemGrabResultPrivate::create(
this, size);
408 connect(window(), &QQuickWindow::beforeSynchronizing, result, &QQuickItemGrabResult::setup, Qt::DirectConnection);
409 connect(window(), &QQuickWindow::afterRendering, result, &QQuickItemGrabResult::render, Qt::DirectConnection);
411 QQuickItemGrabResultPrivate *d = result->d_func();
412 d->qmlEngine = engine;
413 d->callback = callback;
419#include "moc_qquickitemgrabresult.cpp"
QQuickItemGrabResultPrivate()
~QQuickItemGrabResultPrivate()
void ensureImageInCache() const
QPointer< QQuickWindow > window
QQuickPixmap * cacheEntry
static QQuickItemGrabResult * create(QQuickItem *item, const QSize &size)
QPointer< QQuickItem > item
QT_BEGIN_NAMESPACE const QEvent::Type Event_Grab_Completed