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
qquickanimatedimage.cpp
Go to the documentation of this file.
1// Copyright (C) 2016 The Qt Company Ltd.
2// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
3
6
7#include <QtGui/qguiapplication.h>
8#include <QtQml/qqmlinfo.h>
9#include <QtQml/qqmlfile.h>
10#include <QtQml/qqmlengine.h>
11#include <QtGui/qmovie.h>
12#if QT_CONFIG(qml_network)
13#include <QtNetwork/qnetworkrequest.h>
14#include <QtNetwork/qnetworkreply.h>
15#endif
16
18
20{
21 if (!movie)
22 return nullptr;
23
24 int current = movie->currentFrameNumber();
25 if (!frameMap.contains(current)) {
26 QUrl requestedUrl;
27 QQuickPixmap *pixmap = nullptr;
28 if (engine && !movie->fileName().isEmpty()) {
29 requestedUrl.setUrl(QString::fromUtf8("quickanimatedimage://%1#%2x%3#%4")
30 .arg(movie->fileName())
31 .arg(movie->scaledSize().width())
32 .arg(movie->scaledSize().height())
33 .arg(current));
34 }
35 if (!requestedUrl.isEmpty()) {
37 pixmap = new QQuickPixmap(engine, requestedUrl);
38 else
39 pixmap = new QQuickPixmap(requestedUrl, movie->currentImage());
40 } else {
41 pixmap = new QQuickPixmap;
43 }
44 frameMap.insert(current, pixmap);
45 }
46
47 return frameMap.value(current);
48}
49
55
131{
132 connect(this, &QQuickImageBase::cacheChanged, this, &QQuickAnimatedImage::onCacheChanged);
133 connect(this, &QQuickImageBase::currentFrameChanged, this, &QQuickAnimatedImage::frameChanged);
134 connect(this, &QQuickImageBase::currentFrameChanged, this, &QQuickAnimatedImage::currentFrameChanged);
135 connect(this, &QQuickImageBase::frameCountChanged, this, &QQuickAnimatedImage::frameCountChanged);
136}
137
139{
141#if QT_CONFIG(qml_network)
142 if (d->reply)
143 d->reply->deleteLater();
144#endif
145 delete d->movie;
146 d->clearCache();
147}
148
158{
159 Q_D(const QQuickAnimatedImage);
160 if (!d->movie)
161 return d->paused;
162 return d->movie->state()==QMovie::Paused;
163}
164
166{
168 if (pause == d->paused)
169 return;
170 if (!d->movie) {
171 d->paused = pause;
173 } else {
174 d->movie->setPaused(pause);
175 }
176}
177
197{
198 Q_D(const QQuickAnimatedImage);
199 if (!d->movie)
200 return d->playing;
201 return d->movie->state()!=QMovie::NotRunning;
202}
203
205{
207 if (play == d->playing)
208 return;
209 if (!d->movie) {
210 d->playing = play;
212 return;
213 }
214 if (play)
215 d->movie->start();
216 else
217 d->movie->stop();
218}
219
231{
232 Q_D(const QQuickAnimatedImage);
233 if (!d->movie)
234 return d->presetCurrentFrame;
235 return d->movie->currentFrameNumber();
236}
237
239{
241 if (!d->movie) {
242 d->presetCurrentFrame = frame;
243 return;
244 }
245 d->movie->jumpToFrame(frame);
246}
247
249{
250 Q_D(const QQuickAnimatedImage);
251 if (!d->movie)
252 return 0;
253 return d->movie->frameCount();
254}
255
266{
267 Q_D(const QQuickAnimatedImage);
268 return d->speed;
269}
270
272{
274 if (d->speed != speed) {
275 d->speed = speed;
276 if (d->movie)
277 d->movie->setSpeed(qRound(speed * 100.0));
278 emit speedChanged();
279 }
280}
281
283{
285 if (url == d->url)
286 return;
287
288#if QT_CONFIG(qml_network)
289 if (d->reply) {
290 d->reply->deleteLater();
291 d->reply = nullptr;
292 }
293#endif
294
295 d->setImage(QImage());
296 d->oldPlaying = isPlaying();
297 d->setMovie(nullptr);
298 d->url = url;
299 emit sourceChanged(d->url);
300
302 load();
303}
304
306{
308
309 if (d->url.isEmpty()) {
310 d->setProgress(0);
311
312 d->setImage(QImage());
313 if (sourceSize() != d->oldSourceSize) {
314 d->oldSourceSize = sourceSize();
316 }
317
318 d->setStatus(Null);
319 if (isPlaying() != d->oldPlaying)
321 } else {
322 const qreal targetDevicePixelRatio = (window() ? window()->effectiveDevicePixelRatio() : qApp->devicePixelRatio());
323 d->devicePixelRatio = 1.0;
324
325 const auto context = qmlContext(this);
326 QUrl loadUrl = context ? context->resolvedUrl(d->url) : d->url;
327 const QUrl resolvedUrl = loadUrl;
328 resolve2xLocalFile(resolvedUrl, targetDevicePixelRatio, &loadUrl, &d->devicePixelRatio);
330
331 d->status = Null; // reset status, no emit
332
333 if (!lf.isEmpty()) {
334 d->setMovie(new QMovie(lf));
335 movieRequestFinished();
336 } else {
337#if QT_CONFIG(qml_network)
338 if (d->reply)
339 return;
340
341 d->setStatus(Loading);
342 d->setProgress(0);
343 QNetworkRequest req(d->url);
345
346 d->reply = qmlEngine(this)->networkAccessManager()->get(req);
347 connect(d->reply, &QNetworkReply::finished, this, &QQuickAnimatedImage::movieRequestFinished);
348 connect(d->reply, SIGNAL(downloadProgress(qint64,qint64)), this, SLOT(requestProgress(qint64,qint64)));
349#endif
350 }
351 }
352}
353
354void QQuickAnimatedImage::movieRequestFinished()
355{
357
358#if QT_CONFIG(qml_network)
359 if (d->reply) {
360 auto movie = new QMovie(d->reply);
361 // From this point, we no longer need to handle the reply.
362 // I.e. it will be used only as a data source for QMovie,
363 // so it should live as long as the movie lives.
364 d->reply->disconnect(this);
365 d->reply->setParent(movie);
366 d->reply = nullptr;
367
368 d->setMovie(movie);
369 }
370#endif
371
372 if (!d->movie || !d->movie->isValid()) {
373 const QQmlContext *context = qmlContext(this);
374 qmlWarning(this) << "Error Reading Animated Image File "
375 << (context ? context->resolvedUrl(d->url) : d->url).toString();
376 d->setMovie(nullptr);
377
378 d->setImage(QImage());
379 if (sourceSize() != d->oldSourceSize) {
380 d->oldSourceSize = sourceSize();
382 }
383
384 d->setProgress(0);
385 d->setStatus(Error);
386
387 if (isPlaying() != d->oldPlaying)
389 return;
390 }
391
392 connect(d->movie, &QMovie::stateChanged, this, &QQuickAnimatedImage::playingStatusChanged);
393 connect(d->movie, &QMovie::frameChanged, this, &QQuickAnimatedImage::movieUpdate);
394 if (d->cache)
395 d->movie->setCacheMode(QMovie::CacheAll);
396 d->movie->setSpeed(qRound(d->speed * 100.0));
397
398 d->setProgress(1);
399
400 bool pausedAtStart = d->paused;
401 if (d->movie && d->playing)
402 d->movie->start();
403 if (d->movie && pausedAtStart)
404 d->movie->setPaused(true);
405 if (d->movie && (d->paused || !d->playing)) {
406 d->movie->jumpToFrame(d->presetCurrentFrame);
407 d->presetCurrentFrame = 0;
408 }
409
410 QQuickPixmap *pixmap = d->infoForCurrentFrame(qmlEngine(this));
411 if (pixmap) {
412 d->setPixmap(*pixmap);
413 if (sourceSize() != d->oldSourceSize) {
414 d->oldSourceSize = sourceSize();
416 }
417 }
418
419 d->setStatus(Ready);
420
421 if (isPlaying() != d->oldPlaying)
423}
424
425void QQuickAnimatedImage::movieUpdate()
426{
428
429 if (!d->cache)
430 d->clearCache();
431
432 if (d->movie) {
433 d->setPixmap(*d->infoForCurrentFrame(qmlEngine(this)));
434 emit QQuickImageBase::currentFrameChanged();
435 }
436}
437
438void QQuickAnimatedImage::playingStatusChanged()
439{
441
442 if ((d->movie->state() != QMovie::NotRunning) != d->playing) {
443 d->playing = (d->movie->state() != QMovie::NotRunning);
445 }
446 if ((d->movie->state() == QMovie::Paused) != d->paused) {
447 d->paused = (d->movie->state() == QMovie::Paused);
449 }
450}
451
452void QQuickAnimatedImage::onCacheChanged()
453{
455 if (!cache()) {
456 d->clearCache();
457 if (d->movie)
458 d->movie->setCacheMode(QMovie::CacheNone);
459 } else {
460 if (d->movie)
461 d->movie->setCacheMode(QMovie::CacheAll);
462 }
463}
464
466{
467 QQuickItem::componentComplete(); // NOT QQuickImage
468 load();
469}
470
472{
473 if (movie == m)
474 return;
475
477 const int oldFrameCount = q->frameCount();
478
479 if (movie) {
480 movie->disconnect();
482 }
483
484 movie = m;
485 clearCache();
486
487 if (movie)
489
490 if (oldFrameCount != q->frameCount())
491 emit q->frameCountChanged();
492}
493
495
496#include "moc_qquickanimatedimage_p.cpp"
\inmodule QtGui
Definition qimage.h:37
iterator insert(const Key &key, const T &value)
Definition qmap.h:688
T value(const Key &key, const T &defaultValue=T()) const
Definition qmap.h:357
bool contains(const Key &key) const
Definition qmap.h:341
void clear()
Definition qmap.h:289
\inmodule QtGui
Definition qmovie.h:28
QImage currentImage() const
Returns the current frame as a QImage.
Definition qmovie.cpp:770
int currentFrameNumber() const
Returns the sequence number of the current frame.
Definition qmovie.cpp:837
@ Paused
Definition qmovie.h:36
@ NotRunning
Definition qmovie.h:35
@ CacheAll
Definition qmovie.h:42
@ CacheNone
Definition qmovie.h:41
QSize scaledSize()
Definition qmovie.cpp:982
QString fileName() const
Returns the name of the file that QMovie reads image data from.
Definition qmovie.cpp:673
void stateChanged(QMovie::MovieState state)
This signal is emitted every time the state of the movie changes.
void frameChanged(int frameNumber)
void setScaledSize(const QSize &size)
Definition qmovie.cpp:995
void finished()
This signal is emitted when the reply has finished processing.
The QNetworkRequest class holds a request to be sent with QNetworkAccessManager.
void setAttribute(Attribute code, const QVariant &value)
Sets the attribute associated with code code to be value value.
static bool disconnect(const QObject *sender, const char *signal, const QObject *receiver, const char *member)
\threadsafe
Definition qobject.cpp:3236
void deleteLater()
\threadsafe
Definition qobject.cpp:2435
The QQmlContext class defines a context within a QML engine.
Definition qqmlcontext.h:25
The QQmlEngine class provides an environment for instantiating QML components.
Definition qqmlengine.h:57
static QString urlToLocalFileOrQrc(const QString &)
If url is a local file returns a path suitable for passing to \l{QFile}.
Definition qqmlfile.cpp:742
QQuickPixmap * infoForCurrentFrame(QQmlEngine *engine)
QMap< int, QQuickPixmap * > frameMap
void componentComplete() override
Invoked after the root component that caused this instantiation has completed construction.
void setSource(const QUrl &) override
bool isPlaying() const
\qmlproperty bool QtQuick::AnimatedImage::playing This property holds whether the animated image is p...
void setCurrentFrame(int frame) override
QQuickAnimatedImage(QQuickItem *parent=nullptr)
\qmltype AnimatedImage \instantiates QQuickAnimatedImage \inqmlmodule QtQuick \inherits Image
bool isPaused() const
\qmlproperty bool QtQuick::AnimatedImage::paused This property holds whether the animated image is pa...
void sourceSizeChanged()
static void resolve2xLocalFile(const QUrl &url, qreal targetDevicePixelRatio, QUrl *sourceUrl, qreal *sourceDevicePixelRatio)
void sourceChanged(const QUrl &)
The QQuickImageProviderOptions class provides options for QQuickImageProviderWithOptions image reques...
The QQuickItem class provides the most basic of all visual items in \l {Qt Quick}.
Definition qquickitem.h:63
void componentComplete() override
\reimp Derived classes should call the base class method before adding their own actions to perform a...
bool isComponentComplete() const
Returns true if construction of the QML component is complete; otherwise returns false.
static bool isCached(const QUrl &url, const QRect &requestRegion, const QSize &requestSize, const int frame, const QQuickImageProviderOptions &options)
void setImage(const QImage &)
void setPixmap(const QQuickPixmap &other)
\inmodule QtCore\reentrant
Definition qrect.h:30
\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
bool isEmpty() const noexcept
Returns true if the string has no characters; otherwise returns false.
Definition qstring.h:192
static QString fromUtf8(QByteArrayView utf8)
This is an overloaded member function, provided for convenience. It differs from the above function o...
Definition qstring.cpp:6018
\inmodule QtCore
Definition qurl.h:94
QString url(FormattingOptions options=FormattingOptions(PrettyDecoded)) const
Returns a string representation of the URL.
Definition qurl.cpp:2817
qDeleteAll(list.begin(), list.end())
Combined button and popup list for selecting options.
static void * context
#define qApp
int qRound(qfloat16 d) noexcept
Definition qfloat16.h:327
#define SLOT(a)
Definition qobjectdefs.h:52
#define SIGNAL(a)
Definition qobjectdefs.h:53
const GLfloat * m
GLdouble GLdouble GLdouble GLdouble q
Definition qopenglext.h:259
QQmlEngine * qmlEngine(const QObject *obj)
Definition qqml.cpp:80
QQmlContext * qmlContext(const QObject *obj)
Definition qqml.cpp:75
Q_QML_EXPORT QQmlInfo qmlWarning(const QObject *me)
static QUrl resolvedUrl(const QUrl &url, const QQmlRefPointer< QQmlContextData > &context)
SSL_CTX int void * arg
#define emit
long long qint64
Definition qtypes.h:60
double qreal
Definition qtypes.h:187
QUrl url("example.com")
[constructor-url-reference]
connect(quitButton, &QPushButton::clicked, &app, &QCoreApplication::quit, Qt::QueuedConnection)
widget render & pixmap
aWidget window() -> setWindowTitle("New Window Title")
[2]
QFrame frame
[0]
char * toString(const MyType &t)
[31]
QJSEngine engine
[0]