Important: Please read the Qt Code of Conduct - https://forum.qt.io/topic/113070/qt-code-of-conduct

Passing QImage to QML



  • Right now i have got a Delegate of a PathView which Inherits a Image which get's its source from the PathView Model. I am passing the source of my QImage's to my PathView Model by adding it as a ContextProperty to my Model. But what i need is to pass the Image directly to QML, not just the Url to it. I've read about QDeclarativeImageProvider, but in fact it also just provides a Url to be passed to QML. Is there any way to pass a QImage to a QML Delegate Image?

    --Attach--
    Alright, i tried to pass a QAbstractItemModel to QML just to test if QML provides a Qt::DecorationRole in the data function, but it only access rowCount(const QModelIndex &parent). Every necessary function could be accessed by a TreeView. Does a QML Model get his Data only trough a Q_PROPERTY?





  • Thanks for your reply Vincent007,
    but that doesn't look like what i am searching for. I am trying to implement a QImage or QPixmap in QML without having a path.



  • Request sent to Digia.

    main.cpp:
    @#include "Model.h"
    #include <QDeclarativeContext>
    #include <QDeclarativeView>
    #include <QApplication>
    #include <QTableView>

    int main(int argc, char *argv[])
    {
    QApplication a(argc, argv);
    QDeclarativeView *view = new QDeclarativeView;
    QDeclarativeContext *context = view->rootContext();
    QTableView *table = new QTableView;
    Model *model = new Model(0);

    table->setModel(model);
    view->setSource(QUrl("qrc:/qml/qmlview.qml"));
    context->setContextProperty("listModel", model);
    
    table->show();
    view->show();
    return a.exec&#40;&#41;;
    

    }@

    model.h:
    @#ifndef MODEL_H
    #define MODEL_H

    #include <QModelIndex>

    class Model : public QAbstractTableModel
    {
    Q_OBJECT
    public:
    Model(QObject *parent);
    int rowCount(const QModelIndex &parent = QModelIndex()) const;
    int columnCount(const QModelIndex &parent = QModelIndex()) const;
    QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const;
    };

    #endif // MODEL_H@

    model.cpp:
    @#include "Model.h"

    Model::Model(QObject *parent)
    :QAbstractTableModel(parent)
    {
    }

    int Model::rowCount(const QModelIndex &parent) const
    {
    return 2;
    }
    int Model::columnCount(const QModelIndex &parent) const
    {
    return 2;
    }
    QVariant Model::data(const QModelIndex &index, int role) const
    {
    if(role == Qt::DisplayRole)
    {
    return QString("Row%1, Column%2")
    .arg(index.row() + 1)
    .arg(index.column() +1);
    }
    return QVariant();
    }@

    qmlview.qml:
    @import QtQuick 1.1

    Rectangle {
    ListView {
    id: listView
    model: listModel
    delegate: componentDelegate
    }
    Component {
    id: componentDelegate
    Text {
    text: name
    }
    }
    }@

    src.qrc:
    @<RCC>
    <qresource prefix="/qml">
    <file>qmlview.qml</file>
    </qresource>
    </RCC>@



  • -- Edit --
    Please delete this post, thank you.


  • Qt Champions 2017

    How did you resolve this ?



  • I still could not manage to pass a QImage to QML without using QDeclarativeImageProvider, but i am still waiting for Digias response.
    At least i could manage to get the Model and Data passed to QML. In fact it just needs UserRoles and a QHash:

    model.h
    @class Model : public QAbstractListModel
    {
    Q_OBJECT
    public:
    Model(QObject *parent);
    int rowCount(const QModelIndex &parent = QModelIndex()) const;
    int columnCount(const QModelIndex &parent = QModelIndex()) const;
    QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const;
    enum Roles {
    NameRole = Qt::UserRole + 1,
    ImageRole
    };
    QHash<int, QByteArray> roleNames() const {
    QHash<int ,QByteArray> roles;
    roles[NameRole] = "name";
    roles[ImageRole] = "image";
    return roles;
    }
    };@

    model.cpp
    @#include "Model.h"

    Model::Model(QObject *parent)
    :QAbstractListModel(parent)
    {
    }

    int Model::rowCount(const QModelIndex &parent) const
    {
    return 4;
    }
    int Model::columnCount(const QModelIndex &parent) const
    {
    return 2;
    }
    QVariant Model::data(const QModelIndex &index, int role) const
    {
    if(role == NameRole)
    {
    return QString("Row%1, Column%2")
    .arg(index.row() + 1)
    .arg(index.column() +1);
    }
    return QVariant();
    }@

    main.cpp
    @int main(int argc, char *argv[])
    {
    QApplication a(argc, argv);
    QDeclarativeView *view = new QDeclarativeView;
    QDeclarativeContext *context = view->rootContext();
    Model *model = new Model(0);

    view->setSource(QUrl("qrc:/qml/qmlview.qml"));
    context->setContextProperty("listModel", model);
    
    view->show();
    return a.exec&#40;&#41;;
    

    }@

    src.qrc
    @<RCC>
    <qresource prefix="/qml">
    <file>qmlview.qml</file>
    </qresource>
    </RCC>@

    qmlview.qml
    @import QtQuick 1.1

    Rectangle {
    height: 200; width: 200
    ListView {
    id: listView
    height: 200;
    width: 200;
    model: listModel
    delegate: componentDelegate
    }
    Component {
    id: componentDelegate
    Text {
    text: name
    }
    }
    }@

    In Data() you can check if the role is one of your Roles. If so, you can return something. In this example it returns the current column and row if the Role "NameRole" or Qt::UserRole+1 was providet.
    For further Information please read:

    "Using C++ Models with Qt Quick Views":https://qt-project.org/doc/qt-5.1/qtquick/qtquick-modelviewsdata-cppmodels.html
    "QAbstractItemModel":http://qt-project.org/doc/qt-5.0/qtcore/qabstractitemmodel.html
    "QAbstractListModel":http://qt-project.org/doc/qt-5.0/qtcore/qabstractlistmodel.html

    The first link was very helpfull. I will keep this thread alive and post if there are news from Digia.



  • Answer from Digia:

    bq. As Image requires url, you cannot directly specify QImage for it. One
    option would be to change the QImage to QString and then use the QString as image source. So add images to resource file and use in cpp:
    Constructor:
    @Animal(const QString &type, const QString &size, const QString &image);@
    Adding an animal:
    @model.addAnimal(Animal("Wolf", "Medium", "my_image.png")@
    and then in qml:
    @ListView {
    width: 200; height: 250

    model: myModel
    
    Component {
         id: modelDelegate
         Item {
             width: 180; height: 40
             Row {
                 Text { text: "Animal: " + type + ", " + size }
                 Image {source: image}
             }
         }
     }
    
    delegate: modelDelegate
    

    }@
    Another option would be to use QQuickImageProvider class.
    http://qt-project.org/doc/qt-5.0/qtquick/qquickimageprovider.html
    An example of how to use QQuickImageProvider can be found from:
    \qtdeclarative\examples\quick\imageprovider


Log in to reply