我正在尝试显示 QImage
在 QML 中,可能带有 Image
.目前,我发现了类似 QQuickImageProvider
的内容,我实现并尝试使用,但没有成功。
我有QList
我自己的对象( Item
),它们通过 QAbstractListModel
的子类传递到 QSortFilterProxyModel
的子类,即 QQuickView
的上下文属性.每个Item
在 QList
包含 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);
...
main.qml
...
delegate:
Image {
width: 100
height: 100
source: "image://model/"+item.uuid
}
...
完整的例子可以在下面的link中找到.
关于c++ - 使用模型中的图像提供程序公开多个 QImage,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51382435/