Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • Users
  • Groups
  • Search
  • Get Qt Extensions
  • Unsolved
Collapse
Brand Logo
  1. Home
  2. Qt Development
  3. QML and Qt Quick
  4. How i may create editable list model in C code and use it in qml
QtWS25 Last Chance

How i may create editable list model in C code and use it in qml

Scheduled Pinned Locked Moved QML and Qt Quick
2 Posts 1 Posters 4.2k Views
  • Oldest to Newest
  • Newest to Oldest
  • Most Votes
Reply
  • Reply as topic
Log in to reply
This topic has been deleted. Only users with topic management privileges can see it.
  • Q Offline
    Q Offline
    qVLAD
    wrote on last edited by
    #1

    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));
    }
    }
    @

    1 Reply Last reply
    0
    • Q Offline
      Q Offline
      qVLAD
      wrote on last edited by
      #2

      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]

      1 Reply Last reply
      0

      • Login

      • Login or register to search.
      • First post
        Last post
      0
      • Categories
      • Recent
      • Tags
      • Popular
      • Users
      • Groups
      • Search
      • Get Qt Extensions
      • Unsolved