QDeclarativeImageProvider with images loaded from network
-
I have something like this:
@MyImageProvider::MyImageProvider(QObject *parent) : QObject(parent),
--QDeclarativeImageProvider(QDeclarativeImageProvider::Image)
{
...
}QImage MyImageProvider::requestImage(const QString &id, QSize *size, const QSize &requestedSize)
{
//download from web
...
QNetworkReply *reply = m_netManager->get(request);
connect(reply, SIGNAL(finished()), this, SLOT(downloadFinished()));//What to return? Image is not loaded yet
}
void MyImageProvider::downloadFinished()
{
//How to inform declarative engine that image is loaded?
}@I want to download images from web, and do some operations on them. The problem is QtNetwork doesn't offer blocking I/O, so it's not simple to return image in requestImage method. I could do some blocking with entering event loop, but, in my opionion, is very hackish.
Any other solution?
Thanks in advance,
Toni -
I would like to see a more "async" api for image providers.
Do you think you could use a QWaitCondition in the requestImage-method and have another thread downloading the images and notify when it's done?
Please update this thread if you create a solution.
-
Well, QDeclarativeImageProvider is already supporting async loading (if you are using QImage and use Image::asynchronous to true): loading image will be in low priority thread and will not block the UI.
I think QDeclarativeImageProvider was not designed (or was not planned not to be designed) to be used with loading images from network.
Anyway, my solution will be, after I fill up bug/suggestion report, is to use my own image QML element subclassing QDeclarativeItem.
-
Yes, there's support for executing the requestImage method async but you still need to block in requestImage. You can't simple call requestImage and get a call back (signal) later when the image is loaded.
-
did you guys got a solution? i run into the same problem.
-
huluyige: No, I haven't done anything on this yet because I'm not needing it for the moment :)
-
Neither me. :)
But my idea was, to start download images from network, do some blocking ( using 'waiting in a local event loop' http://doc.qt.nokia.com/qq/qq27-responsive-guis.html ), after that return the downloaded image.
-
HI,
I just had a similar issue. I created new DeclaraticeItem ImageCache with property "source". When setting the "source" of ImageCache in C++, check if it exists, if it does emit signal sourceUpdated and if not query network with url, when network reply finished and new image retrieved save it and then emit sourceUpdated.Here is the qml:
@ImageCache{
id: imagecache
source: image://myimageprovider/mypic.png
Image{
id: image
}
onSourceUpdated:{
image.source=source
}
}@Here is the C++ :
@class ImageCache : public QDeclarativeItem
{
Q_OBJECT
Q_PROPERTY(QString source READ source WRITE setSource );public:
QString source(){
return src;
}
void setSource(QString src){
this.src=src
if(exists(src)){
emit sourceUpdated;
else{
QNetworkReply *reply = m_netManager->get(request);
connect(reply, SIGNAL(finished()), this, SLOT(downloadFinished()));}
}
void downloadFinished()
{
QImage img;
img.loadFromData(reply->readAll());
img.save(<path>)
emit sourceUpdated;
}
signal:
void sourceUpdated();private:
QString src;
}@ -
I created a class in C++ that loads a image and stores cache locally then returns local cache path through cache property.
QML code is like this.
@ // MyImage.qml
Item {
width: image.sourceSize.width
height: image.sourceSize.height
property alias source: imageLoader.source
property alias smooth: image.smoothImage { id: image anchors.fill: parent source: imageLoader.cache } ImageLoader { id: imageLoader }
}@