I have a model and a qml.
Model.cpp:
Model::Model(QObject *parent): QAbstractListModel(parent)
{
}
void Model::addIcon(const QString &iconName, const QString &iconPath)
{
beginInsertRows(QModelIndex(), rowCount(), rowCount());
if(!indexMap.contains(iconName)) {
paths.append(iconPath);
indexMap.insert(iconName,paths.indexOf(iconPath));
}
else {
//Update the icon for the designated icon
paths[indexMap.value(iconName)] = iconPath;
QModelIndex index = createIndex(indexMap.value(iconName),1);
emit dataChanged(index,index);
}
endInsertRows();
}
QVariant Model::data(const QModelIndex &index, int role) const
{
if (index.row() < 0 || index.row() >= indexMap.count())
return QVariant();
return paths.at(index.row());
}
int Model::rowCount(const QModelIndex &parent) const
{
Q_UNUSED(parent)
return paths.count();
}
QHash<int, QByteArray> Model::roleNames() const
{
QHash<int, QByteArray> roles;
roles[PathRole] = "iconImage";
return roles;
}
Model.h
class Model : public QAbstractListModel {
Q_OBJECT
public:
enum MyRoles {
PathRole = Qt::UserRole + 1
};
Q_ENUM(MyRoles)
explicit Model(QObject *parent = 0);
QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const;
int rowCount(const QModelIndex &parent = QModelIndex()) const;
QHash<int, QByteArray> roleNames() const;
void addIcon(const QString &iconName, const QString &iconPath);
private:
QList<QString> paths;
QMap<QString,int> indexMap;
};
Wrapper:
Q_PROPERTY(MyModel* modelProperty READ getModel NOTIFY modelChanged)
Qml:
import QtQuick 2.5
Rectangle{
width:100
height:30
ListView{
id:icons
property alias myModel: myService.modelProperty
anchors.fill: parent
anchors.topMargin: 10
anchors.rightMargin: 20
model: myModel
delegate: Image{source: iconImage}
}
}
When I set the icon for the first time, it gives me no error message. Put after the first assignment I get the error "unable to assign [undefined] to QUrl".
I add the new icon path with addIcon method in the model.
Do you have any idea why this could be happening?
Thanks in advance.
The warning means you returned invalid value from data
.
#include <QAbstractListModel>
#define Invalid -1
class Model : public QAbstractListModel
{
Q_OBJECT
public:
struct Icon {
QString name;
QString path;
};
Q_INVOKABLE void add(QString name, QString path) {
add({name, path});
}
void add(const Icon& icon) {
const int& i = find(icon.name);
if(i != Invalid) {
mIconPaths[i].path = icon.path;
emit dataChanged(index(i), index(i)); // Do not add beginInsertRows
} else {
beginInsertRows(QModelIndex(), rowCount(), rowCount());
mIconPaths.push_back(icon);
endInsertRows();
}
}
int find(const QString& name) {
for(int i = 0; i < mIconPaths.size(); i++)
if(mIconPaths[i].name == name)
return i;
return Invalid;
}
QVariant data(const QModelIndex &index, int role) const
{
Q_UNUSED(role)
if (index.row() < 0 || index.row() >= rowCount())
return QVariant();
return mIconPaths.at(index.row()).path;
}
int rowCount(const QModelIndex &parent = QModelIndex()) const
{
Q_UNUSED(parent)
return mIconPaths.count();
}
QHash<int, QByteArray> roleNames() const
{
QHash<int, QByteArray> roles;
roles[0] = "icon";
return roles;
}
private:
QList<Icon> mIconPaths;
};
Test QML:
Window
{
visible: true
height: 640
width: 480
ListView {
anchors.fill: parent
model: myModel
delegate: Text{
text: icon
}
Component.onCompleted: {
myModel.add("test", "test")
myModel.add("test", "modified")
myModel.add("test2", "added")
}
}
}