我正在尝试在QML中显示QImage
,可能与Image
一起显示。目前,我发现了QQuickImageProvider
之类的东西,我实现并尝试使用它,但没有成功。
我有QList
个自己的对象(Item
),这些对象通过QAbstractListModel
的子类传递给QSortFilterProxyModel
的子类,即{{1 }}。 QQuickView
中的每个Item
都包含QList
作为属性。我试图将QImage
属性更改为QImage
,但是无法为每个ImageProvider
向QQuickView->engine
添加图像提供程序。
我尝试使用Item
将ImageProvider
公开为Item
属性,但这与直接引用Q_PROPERTY
的结果相同:QImage
Item.h
Unable to assign QImage to QUrl
ImageProvider.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.cpp
#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_;
};
Main.qml
#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();
}
}
正如我所说,我尝试添加GridView {
//....
model:filterModel
delegate: Image {
id: item
//....
source: item.getItemPhoto //item is role name for Item
}
}
而不是ImageProvider
。但是,我不知道如何将它们显示为QImage
。
有人知道问题出在哪里吗?
感谢您的帮助!
答案 0 :(得分:2)
您必须将某些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中找到。
答案 1 :(得分:0)
拍摄所有图像,并使其通过一个ImageProvider
可访问。
在QML中的用法如下:
Image { source: "image://myimageprovider/image05.png" }
要链接URL中使用的“ myimageprovider”字符串,必须按以下方式注册提供程序:
QQmlEngine::addImageProvider("myimageprovider", imageProvider);
您的图像提供程序具有成员功能:
virtual QImage ImageProvider::requestImage(const QString &id, QSize *size, const QSize &requestedSize);
Qt将URL中的“ image05.png”字符串作为该const QString &id
参数传递。