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]


Log in to reply
 

Looks like your connection to Qt Forum was lost, please wait while we try to reconnect.