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 qmlEngine->handle()->memoryManager->changeUnmanagedHeapSizeUsage(-image.sizeInBytes());
50 bool hasCallback()
const {
return qmlEngine && callback.isCallable(); }
53 if (url.isEmpty() && !image.isNull()) {
54 url.setScheme(QQuickPixmap::itemGrabberScheme);
55 url.setPath(QVariant::fromValue(item.data()).toString());
56 static uint counter = 0;
57 url.setFragment(QString::number(++counter));
58 cacheEntry =
new QQuickPixmap(url, image);
62 static QQuickItemGrabResult *
create(QQuickItem *item,
const QSize &size);
81
82
83
84
85
86
87
88
89
90
91
92
95
96
97
98
99
100
101
102
103
104
107
108
109
110
111
114
115
116
117
118
119
120
123
124
125
126
127
128
131
132
133
134
137
138
139
140
141
142
143
144
145
146
147
148
150QQuickItemGrabResult::QQuickItemGrabResult(QObject *parent)
151 : QObject(*
new QQuickItemGrabResultPrivate, parent)
156
157
158
159
160
164
165
166
167
168
169bool QQuickItemGrabResult::saveToFile(
const QString &fileName)
const
171 Q_D(
const QQuickItemGrabResult);
172 if (fileName.startsWith(QLatin1String(
"file:/")))
173 return saveToFile(QUrl(fileName));
174 return d->image.save(fileName);
178
179
180
181
182
183
184bool QQuickItemGrabResult::saveToFile(
const QUrl &filePath)
const
186 Q_D(
const QQuickItemGrabResult);
187 if (!filePath.isLocalFile()) {
188 qWarning() <<
"saveToFile can only save to a file on the local filesystem";
191 return d->image.save(filePath.toLocalFile());
194#if QT_VERSION < QT_VERSION_CHECK(6
, 0
, 0
)
195#if QT_DEPRECATED_SINCE(5
, 15
)
197
198
199
200bool QQuickItemGrabResult::saveToFile(
const QString &fileName)
202 return std::as_const(*
this).saveToFile(fileName);
207QUrl QQuickItemGrabResult::url()
const
209 Q_D(
const QQuickItemGrabResult);
210 d->ensureImageInCache();
214QImage QQuickItemGrabResult::image()
const
216 Q_D(
const QQuickItemGrabResult);
221
222
223bool QQuickItemGrabResult::event(QEvent *e)
225 Q_D(QQuickItemGrabResult);
226 if (e->type() == Event_Grab_Completed) {
227 if (d->hasCallback()) {
229 d->callback.call(QJSValueList() << d->qmlEngine->newQObject(
this));
230 QQmlEngine::setObjectOwnership(
this, QQmlEngine::JavaScriptOwnership);
236 return QObject::event(e);
239void QQuickItemGrabResult::setup()
241 Q_D(QQuickItemGrabResult);
243 disconnect(d->window.data(), &QQuickWindow::beforeSynchronizing,
this, &QQuickItemGrabResult::setup);
244 disconnect(d->window.data(), &QQuickWindow::afterRendering,
this, &QQuickItemGrabResult::render);
245 QCoreApplication::postEvent(
this,
new QEvent(Event_Grab_Completed));
249 QSGRenderContext *rc = QQuickWindowPrivate::get(d->window.data())->context;
250 d->devicePixelRatio = d->window->effectiveDevicePixelRatio();
251 d->texture = rc->sceneGraphContext()->createLayer(rc);
252 d->texture->setDevicePixelRatio(d->devicePixelRatio);
253 d->texture->setItem(QQuickItemPrivate::get(d->item)->itemNode());
254 d->itemSize = QSizeF(d->item->width(), d->item->height());
257void QQuickItemGrabResult::render()
259 Q_D(QQuickItemGrabResult);
263 d->texture->setRect(QRectF(0, d->itemSize.height(), d->itemSize.width(), -d->itemSize.height()));
264 const QSize minSize = QQuickWindowPrivate::get(d->window.data())->context->sceneGraphContext()->minimumFBOSize();
265 const QSize effectiveTextureSize = d->textureSize * d->devicePixelRatio;
266 d->texture->setSize(QSize(qMax(minSize.width(), effectiveTextureSize.width()),
267 qMax(minSize.height(), effectiveTextureSize.height())));
268 d->texture->scheduleUpdate();
269 d->texture->updateTexture();
271 const qsizetype oldImageSize = d->image.sizeInBytes();
272 d->image = d->texture->toImage();
273 d->image.setDevicePixelRatio(d->devicePixelRatio);
274 const qsizetype newImageSize = d->image.sizeInBytes();
275 if (d->hasCallback()) {
283 d->qmlEngine->handle()->memoryManager->changeUnmanagedHeapSizeUsage(
284 newImageSize - oldImageSize);
288 d->texture =
nullptr;
290 disconnect(d->window.data(), &QQuickWindow::beforeSynchronizing,
this, &QQuickItemGrabResult::setup);
291 disconnect(d->window.data(), &QQuickWindow::afterRendering,
this, &QQuickItemGrabResult::render);
292 QCoreApplication::postEvent(
this,
new QEvent(Event_Grab_Completed));
297 QSize size = targetSize;
299 size = QSize(item->width(), item->height());
301 if (size.width() < 1 || size.height() < 1) {
302 qmlWarning(item) <<
"grabToImage: item has invalid dimensions";
306 if (!item->window()) {
307 qmlWarning(item) <<
"grabToImage: item is not attached to a window";
311 QWindow *effectiveWindow = item->window();
312 if (QWindow *renderWindow = QQuickRenderControl::renderWindowFor(item->window()))
313 effectiveWindow = renderWindow;
315 if (!effectiveWindow->isVisible()) {
316 qmlWarning(item) <<
"grabToImage: item's window is not visible";
320 QQuickItemGrabResult *result =
new QQuickItemGrabResult();
323 d->window = item->window();
324 d->textureSize = size;
326 QQuickItemPrivate::get(item)->refFromEffectItem(
false);
329 item->window()->update();
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352QSharedPointer<QQuickItemGrabResult> QQuickItem::grabToImage(
const QSize &targetSize)
354 QQuickItemGrabResult *result = QQuickItemGrabResultPrivate::create(
this, targetSize);
356 return QSharedPointer<QQuickItemGrabResult>();
358 connect(window(), &QQuickWindow::beforeSynchronizing, result, &QQuickItemGrabResult::setup, Qt::DirectConnection);
359 connect(window(), &QQuickWindow::afterRendering, result, &QQuickItemGrabResult::render, Qt::DirectConnection);
361 return QSharedPointer<QQuickItemGrabResult>(result);
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
395
396
397
398bool QQuickItem::grabToImage(
const QJSValue &callback,
const QSize &targetSize)
400 QQmlEngine *engine = qmlEngine(
this);
402 qmlWarning(
this) <<
"grabToImage: item has no QML engine";
406 if (!callback.isCallable()) {
407 qmlWarning(
this) <<
"grabToImage: 'callback' is not a function";
411 QSize size = targetSize;
413 size = QSize(width(), height());
415 if (size.width() < 1 || size.height() < 1) {
416 qmlWarning(
this) <<
"grabToImage: item has invalid dimensions";
421 qmlWarning(
this) <<
"grabToImage: item is not attached to a window";
425 QQuickItemGrabResult *result = QQuickItemGrabResultPrivate::create(
this, size);
429 connect(window(), &QQuickWindow::beforeSynchronizing, result, &QQuickItemGrabResult::setup, Qt::DirectConnection);
430 connect(window(), &QQuickWindow::afterRendering, result, &QQuickItemGrabResult::render, Qt::DirectConnection);
432 QQuickItemGrabResultPrivate *d = result->d_func();
433 d->qmlEngine = engine;
434 d->callback = callback;
440#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
Combined button and popup list for selecting options.
QT_BEGIN_NAMESPACE const QEvent::Type Event_Grab_Completed