[Qt-qml] Returning a QImage to QML from C++ for a ListView delegate...

Jerzy Chalupski jerzy.chalupski at gmail.com
Fri Nov 19 18:41:42 CET 2010


QDeclarativeImageProvider is not an QObject, so the model and image
provider might be implemented in the same class:

class MyAwesomeModel: public QAbstractItemModel, public
QDeclarativeImageProvider
{
//...
};

The upside of this solution is that you can have a single data
structure, so you don't have to implement data synchronization between
model and image provider.

2010/11/19  <ray.rischpater at nokia.com>:
> Actually, you can return different images using the QDeclarativeImageProvider and a C++ model --- simply have a role in the model return a different string resource name for each model item (e.g., "image://model/1.png", "image://model/2.png", and so forth), and then have the image provider return the appropriate image from the model. If you want to be a bit faster, you can even have your image provider use a QMap<QString, QModelIndex> to map from the image's name in the model to the image. Based on Juha's feedback, I've got code running now I'm planning on cleaning up a bit and posting to my blog in the near future. The crux of the code is the requestPixmap method, which looks like this:
>
> class QAbstractItemModel;
>
> class ModelIndexProvider : public QObject, public QDeclarativeImageProvider
> {
>    Q_OBJECT
> public:
>    ModelIndexProvider(QAbstractItemModel& model, int pathRole, int pixmapRole, QObject* parent = 0);
>    ~ModelIndexProvider();
>    QPixmap requestPixmap(const QString& id, QSize* size, const QSize& requestedSize);
>
> public slots:
>    void dataUpdated(const QModelIndex & topLeft, const QModelIndex & bottomRight);
>    void dataDeleted(const QModelIndex & parent, int start, int end);
>    void dataReset();
>
> private:
>    QAbstractItemModel& mModel;
>    int mPathRole;
>    int mPixmapRole;
>    QMap<QString, QModelIndex> mPixmapIndex;
> };
>
> QPixmap ModelIndexProvider::requestPixmap(const QString& id, QSize* size, const QSize& requestedSize)
> {
>    QString key = QString("image://model/%1").arg(id);
>    QModelIndex index = mPixmapIndex[key];
>    QPixmap image = mModel.data(index, mPixmapRole).value<QPixmap>();
>    QPixmap result;
>
>    if (requestedSize.isValid()) {
>        result = image.scaled(requestedSize, Qt::KeepAspectRatio);
>    } else {
>        result = image;
>    }
>    *size = result.size();
>    return result;
> }
>
> Of course, the provider should be a QObject and connect to the model so that when the model changes the pixmap index gets updated and so forth, but that's pretty easy.
>
> Thanks again to Juha for the suggestion!
>
> On Nov 18, 2010, at 10:56 PM, ext Tuomas Niinistö wrote:
>
>> Juha Turunen <turunen at ...> writes:
>>
>>>
>>> Hi Ray,
>>>
>>> [ Use QDeclarativeImageProvider ]
>>>
>>> On Fri, Nov 12, 2010 at 7:42 PM,  <ray.rischpater at ...> wrote:
>>>> [ Question about returning images from models ]
>>>> Nokia Research Center Palo Alto
>>
>> Hi,
>>
>> I have faced the same problem as Ray. And think that the
>> QDeclarativeImageProvider does not help here, at least not directly.
>>
>> When you have a list object existing in native C++ side and you wan't to
>> populate the QML ListView with it. For "normal" data like integers and strings
>> it works fine by using QDeclarativeListProperty.
>>
>> But the problem comes when you want to have an individual image for each list
>> item. With QDeclarativeImageProvider you can populate the list items with the
>> same image instance, but how to have an individual image for each item seems to
>> be problematic.
>>
>> Br, Tuomas
>>
>>
>>
>>
>> _______________________________________________
>> Qt-qml mailing list
>> Qt-qml at trolltech.com
>> http://lists.trolltech.com/mailman/listinfo/qt-qml
>
>
> _______________________________________________
> Qt-qml mailing list
> Qt-qml at trolltech.com
> http://lists.trolltech.com/mailman/listinfo/qt-qml
>




More information about the Qt-qml mailing list