Important: Please read the Qt Code of Conduct - https://forum.qt.io/topic/113070/qt-code-of-conduct

Listview with custom elements (QAbstractListModel with derived classes)



  • Hello, I'm working on a Qt qml application which has a listview containing multiple different items each with their own unique properties.
    I've managed to make it work using a QAbstractListModel, however the implementation isn't modular and expanding upon my current method won't be pretty.

    QVariant ProcessingModel::data(const QModelIndex &index, int role) const
    {
      if (index.row() < 0 || index.row() >= m_model.count())
              return QVariant();
    
      ImageProcess* process = m_model[index.row()];
      switch(role)
      {
        default:
          return QVariant();
        case TypeNameRole:
          return process->type_name();
        case TypeRole:
          return process->type();
        case ErosionSize:
          return static_cast<Erode*>(process)->erosion_size();
        case DilationSize:
          return static_cast<Dilate*>(process)->dilation_size();
      }
    }
    
    QHash<int, QByteArray> ProcessingModel::roleNames() const {
        QHash<int, QByteArray> roles;
        roles[TypeNameRole] = "type_name";
        roles[TypeRole] = "type";
        roles[ErosionSize] = "erosion_size";
        roles[DilationSize] = "dilation_size";
        return roles;
    }
    

    The application currently looks like this:
    display.PNG
    This list currently contains two items: Erode and Dilate, each item is expandable showing their own custom menu. (in the image Dilate is expanded showing some text and a slider which changes the dilation_size)

    How can i make a QAbstractListModel using derived classes?
    Or is there something else I should use instead?

    Any feedback or advice is welcome, thanks in advance.



  • Fixed it by moving the data aspect to the derived classes (du-duh)
    Only thing that still stings is the roleNames function requiring to ask each derived class for its rolenames, for which i don't see an easy solution. but it is only one additional line for each derived class, which I can live with.

    QVariant ProcessingModel::data(const QModelIndex &index, int role) const
    {
      if (index.row() < 0 || index.row() >= m_model.count())
              return QVariant();
    
      return m_model[index.row()]->getData(role);
    }
    
    QHash<int, QByteArray> ProcessingModel::roleNames() const {
        QMultiHash<int, QByteArray> roles;
        roles.insert(ImageProcess::TypeNameRole, "type_name");
        roles.insert(ImageProcess::TypeRole, "type");
        roles.unite(Erode::roleNames());
        roles.unite(Dilate::roleNames());
        return std::move(roles);
    }
    

    If anyone has any suggestions on how to improve the roleNames feel free to share.


Log in to reply