c++ - 使用模型中的图像提供程序公开多个 QImage

标签 c++ qt qml

我正在尝试显示 QImage在 QML 中,可能带有 Image .目前,我发现了类似 QQuickImageProvider 的内容,我实现并尝试使用,但没有成功。

我有QList我自己的对象( Item ),它们通过 QAbstractListModel 的子类传递到 QSortFilterProxyModel 的子类,即 QQuickView 的上下文属性.每个ItemQList包含 QImage作为一个属性。我试图改变 QImage属性为 ImageProvider , 但无法将图像提供程序添加到 QQuickView->engine对于每个 Item .

我试图揭露 ImageProvider作为Item属性为 Q_PROPERTY , 但它与直接引用 QImage 的结果相同: Unable to assign QImage to QUrl

Item.h

#include <QObject>
#include <QImage>
#include "ImageProvider.h"

class Item : public QObject
{
    Q_OBJECT
    Q_PROPERTY(QImage getItemPhoto READ getItemPhoto WRITE setItemPhoto NOTIFY photoChanged)

public:
    // ---- PUBLIC METHODS ----
    //! Sets up unique ID for Item
    explicit Item();

    //! Returns image source path
    QImage getItemPhoto() const { return photo_; }

    //! Sets source path for the image of the Item
    void setItemPhoto(const QImage &imageSource);

signals:
    // ---- SIGNALS ----

    photoChanged();

private:
    // ---- PRIVATE METHODS ----
    //! Set id of Item
    void setId(const int &ID);

private:
    // ---- PRIVATE ATTRIBUTES ---

    QImage photo_;

    QImage heatMap_;
};

ImageProvider.h

#include <QObject>
#include <QImage>
#include <QQuickImageProvider>

class ImageProvider : public QObject, QQuickImageProvider
{
    Q_OBJECT
public:
    ImageProvider();

    QImage requestImage(const QString &id, QSize *size, const QSize &requestedSize);

public slots:
    void setPhoto(const QImage &photo);

signals:
    void photoChanged();

private:
    QImage photo_;
};

ImageProvider.cpp

#include "ImageProvider.h"

ImageProvider::ImageProvider() : QQuickImageProvider(QQuickImageProvider::Image)
{
    this->blockSignals(false);
}

QImage ImageProvider::requestImage(const QString &id, QSize *size, const QSize &requestedSize)
{
    Q_UNUSED(id)
    QImage res = this->photo_;

    if(res.isNull())
        return QImage();

    if(size)
    {
        *size = res.size();
    }

    if(requestedSize.width() > 0 && requestedSize.height() > 0)
        res = res.scaled(requestedSize.width(), requestedSize.height(), Qt::KeepAspectRatio); //TODO

    return res;
}

void ImageProvider::setPhoto(const QImage &photo)
{
    if(photo_ != photo)
    {
        photo_ = photo;
        emit photoChanged();
    }
}

Main.qml

GridView {
    //.... 
    model:filterModel

    delegate: Image {
        id: item
        //....
        source: item.getItemPhoto //item is role name for Item
    }
}

正如我所说,我尝试添加 ImageProvider而不是 QImage .但是,我不知道如何将它们公开为 QUrl .

谁知道问题出在哪里?

感谢您的帮助!

最佳答案

你必须给图像关联一些id,并将id传递给QQuickImageProvider,在requestImage方法中你必须使用id获取模型的图像。

为此,您必须创建另一个角色,在此示例中调用与具有该值的属性关联的 uuid。

item.h

#ifndef ITEM_H
#define ITEM_H

#include <QImage>
#include <QObject>
#include <QUuid>

class Item : public QObject
{
    Q_OBJECT
    Q_PROPERTY(QImage photo READ photo WRITE setPhoto NOTIFY photoChanged)
    Q_PROPERTY(QUuid uuid READ uuid NOTIFY uuidChanged) // <---id
public:
    using QObject::QObject;

    QImage photo() const {
        return mPhoto;
    }
    void setPhoto(const QImage &photo){
        mPhoto = photo;
        emit  photoChanged();
        mUuid = QUuid::createUuid();
        emit uuidChanged();
    }
    QUuid uuid() const {
        return mUuid;
    }
signals:
    void photoChanged();
    void uuidChanged();
private:
    QImage mPhoto;
    QUuid mUuid;
};

#endif // ITEM_H

itemmodel.h

QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const override{
    if (!index.isValid())
        return QVariant();
     Item *item =  mItems[index.row()];
    if(role == Qt::UserRole){
        return QVariant::fromValue(item);
    }
    else if(role == Qt::UserRole+1){
        return QVariant::fromValue(item->uuid());
    }
    return QVariant();
}

QHash<int, QByteArray> roleNames() const{
    QHash<int, QByteArray> roles;
    roles[Qt::UserRole] = "item";
    roles[Qt::UserRole+1] = "uuid";
    return roles;
}

modelimageprovider.h

#ifndef MODELIMAGEPROVIDER_H
#define MODELIMAGEPROVIDER_H

#include "item.h"

#include <QAbstractListModel>
#include <QQuickImageProvider>
#include <QUuid>

class ModelImageProvider : public QQuickImageProvider
{
public:
    explicit ModelImageProvider(QAbstractItemModel *model)
        :QQuickImageProvider(QQuickImageProvider::Image)
    {
        mModel = model;
    }
    QImage requestImage(const QString &id, QSize *size, const QSize &requestedSize){
        Q_UNUSED(requestedSize)
        Q_UNUSED(size)
        // search item
        QUuid uuid(QByteArray::fromPercentEncoding(id.toLatin1()));
        QModelIndexList indexes = mModel->match(
                    mModel->index(0, 0),
                    Qt::UserRole+1,
                    QVariant::fromValue(uuid),
                    1,
                    Qt::MatchRecursive);
        if(indexes.size() > 0){
            Item *it = qvariant_cast<Item *>(indexes[0].data(Qt::UserRole));
            if(it)
                return it->photo();
        }
        return QImage();
    }
private:
    QAbstractItemModel *mModel;
};

#endif // MODELIMAGEPROVIDER_H

main.cpp

...
ModelImageProvider *provider = new ModelImageProvider(manager.filterModel());
QQmlApplicationEngine engine;
engine.addImageProvider("model", provider);
engine.rootContext()->setContextProperty("manager", &manager);
...

ma​​in.qml

...
delegate:
    Image {
    width: 100
    height: 100
    source: "image://model/"+item.uuid
}
...

完整的例子可以在下面的link中找到.

关于c++ - 使用模型中的图像提供程序公开多个 QImage,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51382435/

相关文章:

c++ - 运行c++程序时vc++出现 fatal error

c++ - QWidget paintEvent 无故停止调用

具有接口(interface)和默认实现的 C++ 继承

Qt QSS 教程

c++ - 如何从 C++ 设置 QML 属性

c++ - 简单的 Flex/Bison C++

c++ - 碰撞。 QObject::connect 在静态对象实例的构造函数中

c++ - `QVirtualKeyboard`的激活和部署(在Windows中)

c++ - Qt/Qml : Custom widget -- cannot set "width" property as it is readonly

android - 在 chrome 下载列表中打开 apk 未打开 apk 安装程序