The QQuickImageProvider::requestTexture() method will be called for all image requests. \omitvalue
*/
+/*!
+ \enum QQmlImageProviderBase::Flag
+
+ Defines specific requirements or features of this image provider.
+
+ \value ForceAsynchronousImageLoading Ensures that image requests to the provider are
+ run in a separate thread, which allows the provider to spend as much time as needed
+ on producing the image without blocking the main thread.
+*/
+
/*! \internal */
QQmlImageProviderBase::QQmlImageProviderBase()
{
Invalid
};
+ enum Flag {
+ ForceAsynchronousImageLoading = 0x01
+ };
+ Q_DECLARE_FLAGS(Flags, Flag)
+
virtual ~QQmlImageProviderBase();
virtual ImageType imageType() const = 0;
+ virtual Flags flags() const = 0;
private:
friend class QQuickImageProvider;
QQmlImageProviderBase();
};
+Q_DECLARE_OPERATORS_FOR_FLAGS(QQmlImageProviderBase::Flags)
class QQmlComponent;
class QQmlEnginePrivate;
{
public:
QQuickImageProvider::ImageType type;
+ QQuickImageProvider::Flags flags;
};
/*!
allowing image loading to be executed in the background, and reducing the
performance impact on the user interface.
+ To force asynchronous image loading, even for image sources that do not
+ have the \c asynchronous property set to \c true, you may pass the
+ \c QQuickImageProvider::ForceAsynchronousImageLoading flag to the image
+ provider constructor. This ensures that all image requests for the
+ provider are handled in a separate thread.
+
Asynchronous loading is not supported for image providers that provide
QPixmap rather than QImage values, as pixmaps can only be created in the
main thread. In this case, if \l {Image::}{asynchronous} is set to
/*!
Creates an image provider that will provide images of the given \a type.
*/
-QQuickImageProvider::QQuickImageProvider(ImageType type)
+QQuickImageProvider::QQuickImageProvider(ImageType type, Flags flags)
: d(new QQuickImageProviderPrivate)
{
d->type = type;
+ d->flags = flags;
}
/*!
}
/*!
+ Returns the flags set for this provider.
+*/
+QQuickImageProvider::Flags QQuickImageProvider::flags() const
+{
+ return d->flags;
+}
+
+/*!
Implement this method to return the image with \a id. The default
implementation returns an empty image.
class Q_QUICK_EXPORT QQuickImageProvider : public QQmlImageProviderBase
{
public:
- QQuickImageProvider(ImageType type);
+ QQuickImageProvider(ImageType type, Flags flags = 0);
virtual ~QQuickImageProvider();
ImageType imageType() const;
+ Flags flags() const;
virtual QImage requestImage(const QString &id, QSize *size, const QSize& requestedSize);
virtual QPixmap requestPixmap(const QString &id, QSize *size, const QSize& requestedSize);
QHash<QQuickPixmapKey, QQuickPixmapData *>::Iterator iter = store->m_cache.find(key);
if (iter == store->m_cache.end()) {
- if (options & QQuickPixmap::Asynchronous) {
- // pixmaps can only be loaded synchronously
- if (url.scheme() == QLatin1String("image")) {
- QQuickImageProvider *provider = static_cast<QQuickImageProvider *>(engine->imageProvider(imageProviderId(url)));
- if (provider && provider->imageType() == QQuickImageProvider::Pixmap) {
+ if (url.scheme() == QLatin1String("image")) {
+ if (QQuickImageProvider *provider = static_cast<QQuickImageProvider *>(engine->imageProvider(imageProviderId(url)))) {
+ if (provider->imageType() == QQuickImageProvider::Pixmap) {
+ // pixmaps can only be loaded synchronously
options &= ~QQuickPixmap::Asynchronous;
+ } else if (provider->flags() & QQuickImageProvider::ForceAsynchronousImageLoading) {
+ options |= QQuickPixmap::Asynchronous;
}
}
}
void requestImage_sync();
void requestImage_async_data();
void requestImage_async();
+ void requestImage_async_forced_data();
+ void requestImage_async_forced();
void requestPixmap_sync_data();
void requestPixmap_sync();
class TestQImageProvider : public QQuickImageProvider
{
public:
- TestQImageProvider(bool *deleteWatch = 0)
- : QQuickImageProvider(Image), deleteWatch(deleteWatch)
+ TestQImageProvider(bool *deleteWatch = 0, bool forceAsync = false)
+ : QQuickImageProvider(Image, (forceAsync ? ForceAsynchronousImageLoading : Flags()))
+ , deleteWatch(deleteWatch)
{
}
QQuickImage *obj = qobject_cast<QQuickImage*>(component.create());
QVERIFY(obj != 0);
- if (async)
+ // From this point on, treat forced async providers as async behaviour-wise
+ if (engine.imageProvider(QUrl(source).host()) == provider)
+ async |= provider->flags() & QQuickImageProvider::ForceAsynchronousImageLoading;
+
+ if (async)
QTRY_VERIFY(obj->status() == QQuickImage::Loading);
QCOMPARE(obj->source(), QUrl(source));
QVERIFY(deleteWatch);
}
+void tst_qquickimageprovider::requestImage_async_forced_data()
+{
+ fillRequestTestsData("qimage|async_forced");
+}
+
+void tst_qquickimageprovider::requestImage_async_forced()
+{
+ bool deleteWatch = false;
+ runTest(false, new TestQImageProvider(&deleteWatch, true));
+ QVERIFY(deleteWatch);
+}
+
void tst_qquickimageprovider::requestPixmap_sync_data()
{
fillRequestTestsData("qpixmap");