QQuickImageProvider提供了一个可以供我们对QPixmap及多线程的Image请求。这个请求的文件甚至可以在网络上。它的好处是:
- 装载一个QPixmap或QImage而不是一个具体的文件
- 在另外一个thread异步装载图片
通过访问一个图片可以通过如下的方式:
Column { Image { source: "image://colors/yellow" } Image { source: "image://colors/red" } }
显然,这里的yellow和red不是文件名。它的提供依赖于在QQuickImageProvider中的requestImage的具体实现。
下面我们来通过一个具体的例程来介绍如何使用QQuickImageProvider来从网路上请求一个我们需要的图像。
myimageprovider.h
#ifndef MYIMAGEPROVIDER_H #define MYIMAGEPROVIDER_H #include <QQuickImageProvider> class QNetworkAccessManager; class MyImageProvider : public QQuickImageProvider { public: MyImageProvider(ImageType type, Flags flags = 0); ~MyImageProvider(); QImage requestImage(const QString & id, QSize * size, const QSize & requestedSize); protected: QNetworkAccessManager *manager; }; #endif // MYIMAGEPROVIDER_H
myimageprovider.cpp
#include "myimageprovider.h" #include <QNetworkAccessManager> #include <QNetworkReply> #include <QEventLoop> MyImageProvider::MyImageProvider(ImageType type, Flags flags) : QQuickImageProvider(type,flags) { manager = new QNetworkAccessManager; } MyImageProvider::~MyImageProvider() { delete manager; } QImage MyImageProvider::requestImage(const QString &id, QSize *size, const QSize &requestedSize) { qDebug() << "id: " << id; qDebug() << "reequestedSize: " << requestedSize.width() + " " + requestedSize.height(); QUrl url("http://lorempixel.com/" + id); QNetworkReply* reply = manager->get(QNetworkRequest(url)); QEventLoop eventLoop; QObject::connect(reply, SIGNAL(finished()), &eventLoop, SLOT(quit())); eventLoop.exec(); if (reply->error() != QNetworkReply::NoError) return QImage(); QImage image = QImage::fromData(reply->readAll()); size->setWidth(image.width()); size->setHeight(image.height()); return image; }
上面我们从网路地址“http://lorempixel.com/”取得文件,并转化为一个QImage。QQuickImageProvider要求我们必须实现如下的一个virtual方法。
QQuickImageProvider(ImageType type, Flags flags = 0) virtual ~QQuickImageProvider() Flags flags() const ImageType imageType() const virtual QImage requestImage(const QString & id, QSize * size, const QSize & requestedSize) virtual QPixmap requestPixmap(const QString & id, QSize * size, const QSize & requestedSize) virtual QQuickTextureFactory * requestTexture(const QString & id, QSize * size, const QSize & requestedSize)
我们可以在QML中通过如下的方式来访问一个图片:
Image { source: "image://myprovider/500/500/" }
显然我们看到的source不是一个具体的文件。并且,它的source是以“image://”开始的。
我们在我们的main.cpp中做如下的实现:
#include "myimageprovider.h" int main(int argc, char *argv[]) { QGuiApplication app(argc, argv); QQuickView view; QQmlEngine *engine = view.engine(); MyImageProvider *imageProvider = new MyImageProvider(QQmlImageProviderBase::Image); engine->addImageProvider("myprovider", imageProvider ); view.setSource(QUrl(QStringLiteral("qrc:///Main.qml"))); view.setResizeMode(QQuickView::SizeRootObjectToView); view.show(); return app.exec(); }
注意这里的“myprovider”和我们上面的Image中访问的对应起来。
我们的main.qml文件如下:
main.qml
import QtQuick 2.0 import Ubuntu.Components 1.1 /*! \brief MainView with a Label and Button elements. */ MainView { // objectName for functional testing purposes (autopilot-qt5) objectName: "mainView" // Note! applicationName needs to match the "name" field of the click manifest applicationName: "imageprovider.liu-xiao-guo" /* This property enables the application to change orientation when the device is rotated. The default is false. */ //automaticOrientation: true // Removes the old toolbar and enables new features of the new header. useDeprecatedToolbar: false width: units.gu(60) height: units.gu(85) Page { title: i18n.tr("imageprovider") Image { id: img anchors.centerIn: parent source: "image://myprovider/500/500/" anchors.fill: parent onStatusChanged: { if(status == Image.Ready) indicator.running = false; } ActivityIndicator { id: indicator anchors.centerIn: parent running: false } MouseArea { anchors.fill: parent onClicked: { indicator.running = true; img.source = "image://myprovider/500/500/?seed=" + Math.random(1000) } } } } }
我们在点击图片时,它会自动地随机地从网站取得下一个图片,并显示出来:
整个项目的源码在:git clone https://gitcafe.com/ubuntu/imageprovider.git
版权声明:本文为博主原创文章,未经博主允许不得转载。
时间: 2024-11-06 03:45:27