How i may create editable list model in C code and use it in qml
-
How i may do visible roles in qml? How true used QModelIndex in QML when i want edit value in MenuElement? I
I wrote this code, but it doesn't work. Please help me.@
#ifndef MENUMODEL_H
#define MENUMODEL_H
#include <QAbstractListModel>
#include <QStringList>class MenuElement
{
public:
MenuElement(const QString &fullName, const int &value);
QString fullName() const;
int value() const;
void setFullName(QString value);
void setValue(int value);
private:
QString m_fullName;
int m_value;
};class MenuModel: public QAbstractListModel
{
Q_OBJECT
public:
enum MenuElementRoles {
FullNameRole = Qt::UserRole + 1,
ValueRole,
FullNameRoleEdit,
ValueRoleEdit
};
MenuModel(QObject *parent = 0);void addMenuElement(const MenuElement &MenuElement); int rowCount(const QModelIndex & parent = QModelIndex()) const; Q_INVOKABLE QVariant data(const QModelIndex & index, int role = Qt::DisplayRole) const; Q_INVOKABLE Qt::ItemFlags flags(const QModelIndex &index) const; Q_INVOKABLE bool setData(const QModelIndex &index, const QVariant &value, int role = Qt::EditRole);
public slots:
void debugMessage(){qDebug("Message from QML");}
private:
QList<MenuElement> m_elements;
};#endif // MENUMODEL_H
@@
#include "menumodel.h"MenuElement::MenuElement(const QString &fullName,
const int &value)
: m_fullName(fullName),
m_value(value)
{
}QString MenuElement::fullName() const
{
return m_fullName;
}int MenuElement::value() const
{
return m_value;
}void MenuElement::setFullName(QString value)
{
m_fullName = value;
}void MenuElement::setValue(int value)
{
m_value = value;
}MenuModel::MenuModel(QObject *parent)
: QAbstractListModel(parent)
{
QHash<int, QByteArray> roles;
roles[FullNameRole] = "fullName";
roles[ValueRole] = "value";
roles[FullNameRoleEdit] = "fullNameEdit";
roles[ValueRoleEdit] = "valueEdit";
setRoleNames(roles);
}void MenuModel::addMenuElement(const MenuElement &MenuElement)
{
beginInsertRows(QModelIndex(), rowCount(), rowCount());
m_elements << MenuElement;
endInsertRows();
}int MenuModel::rowCount(const QModelIndex & /parent/) const
{
return m_elements.count();
}QVariant MenuModel::data(const QModelIndex & index, int role) const
{
if (index.row() < 0 || index.row() > m_elements.count())
return QVariant();const MenuElement &MenuElement = m_elements[index.row()]; if (role == FullNameRole) return MenuElement.fullName(); else if (role == ValueRole) return MenuElement.value(); return QVariant();
}
Qt::ItemFlags MenuModel::flags(const QModelIndex &index) const
{
if (!index.isValid())
return Qt::ItemIsEnabled;return QAbstractItemModel::flags(index) | Qt::ItemIsEditable;
}bool MenuModel::setData(const QModelIndex &index, const QVariant &value, int role)
{
if (index.isValid() && role == FullNameRoleEdit) {
MenuElement &MenuElement = m_elements[index.row()];
MenuElement.setFullName(value.toString());
emit dataChanged(index, index);
return true;
}else if(index.isValid() && role == ValueRoleEdit){
MenuElement &MenuElement = m_elements[index.row()];
MenuElement.setValue(value.toInt());
emit dataChanged(index, index);
return true;
}else{
return false;
}
}
@@
Rectangle {
ListView {
id: menuView
width: 200; height: parent.height
model: recMenu
delegate: MenuDelegate{}
focus: true
highlight: MenuHighlight{}
highlightFollowsCurrentItem: true
}
focus:true
Keys.onEnterPressed: {
console.log("Cur:"+menuView.currentIndex+" "+menuView.model.setData(menuView.currentIndex,"new Name",ValueRoleEdit));
}
}
@ -
After these corrections, the data in the model change, but the signal dataДhanged in QML does not redraw ListView. Is it possible to use QModelIndex in QML?
@
Q_INVOKABLE bool setData(const QModelIndex &index, const QVariant &value, int role = Qt::EditRole);
=>
Q_INVOKABLE void setData(/const QModelIndex & index/int index , int role, QVariant new_value);
@@
bool MenuModel::setData(const QModelIndex &index, const QVariant &value, int role)
{
if (index.isValid() && role == FullNameRoleEdit) {
MenuElement &MenuElement = m_elements[index.row()];
MenuElement.setFullName(value.toString());
emit dataChanged(index, index);
return true;
}else if(index.isValid() && role == ValueRoleEdit){
MenuElement &MenuElement = m_elements[index.row()];
MenuElement.setValue(value.toInt());
emit dataChanged(index, index);
return true;
}else{
return false;
}
}@
=>
@
bool MenuModel::setData(const int &index, const QString & field_name, QVariant newValue )
{
if (index < 0 || index > m_elements.count())
return false;
MenuElement &MenuElement = m_elements[index];
qDebug()<<MenuElement.fullName();
MenuElement.setFullName(newValue.toString());
qDebug()<<MenuElement.fullName();
emit dataChanged(QModelIndex(), QModelIndex());
return true;}
@@
console.log("Cur:"+menuView.currentIndex+" "+menuView.model.setData(menuView.currentIndex,"new Name",ValueRoleEdit));
=>
console.log("Cur:"+menuView.currentIndex+""+menuView.model.setData(menuView.currentIndex,"FullName","new Name2"));
@[EDIT: fixed code formatting, Volker]