Qt Forum

    • Login
    • Search
    • Categories
    • Recent
    • Tags
    • Popular
    • Users
    • Groups
    • Search
    • Unsolved

    Unsolved Clearing elements from a QML ListView

    QML and Qt Quick
    1
    1
    237
    Loading More Posts
    • 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.
    • M
      MarkGR last edited by MarkGR

      I have a ListView which uses a C++ model which is populated w/data from a backstore(a SQLite db, in this case). I am now able to correctly bind the model to the view and populate the list. However, when I try to refresh the list(through a slot attached to a Button in the QML), the ListView successfully clears but I am not able to re-load any data on this or any subsequent attempts.

      I am implementing QAbstractItemModel::removeRows but this does not seem to be working correctly. I suspect there may be some QML property I am missing on the ListView object, such as an index counter or something which controls this. I have confirmed that my model correctly contains data when I re-fresh the model. It is just now being displayed in the view.

      My QML code is:

      import QtQuick 2.12
      import QtQuick.Window 2.12
      import QtQuick.Controls 2.12
      
      
      Rectangle {
          visible: true
          width: 640
          height: 480    
          Button {
              id: button
              x: 49
              y: 6
              text: qsTr("View Color Libraries")
              onClicked: colorLibraryViewModel.loadColorLibraries();
          }
      
          ColorLibrariesList {
              width: 532
              height: 324
              anchors.centerIn: parent
          }
      }
      
      import QtQuick 2.12
      import QtQuick.Window 2.12
      import QtQuick.Controls 2.12
      import QtQuick.Layouts 1.3
      import QtGraphicalEffects 1.0
      
      
      ColumnLayout {
          Frame {
              Layout.fillWidth: true
              ListView {
                  id: listView
                  x: 49
                  y: 78
                  implicitWidth: 250
                  implicitHeight: 250
                  clip: true            
                  model: colorLibraryListModel
                  delegate: RowLayout {
                      width: parent.width
                      Text {
                          text: name
                      }
                      Image {                    
                          source: type
                      }
                      Text {                    
                          text: isReadOnly
                      }
               }
           }
          }
      }
      
      

      My view/model class, as I call it(which handles the binding of my model to the QQmlContext), is defined and implemented as such:

      #ifndef COLORLIBRARYVIEWMODEL_H
      #define COLORLIBRARYVIEWMODEL_H
      
      #include <QObject>
      #include <QQuickView>
      #include "datasourceinterface.h"
      #include "ColorLibraryListModel.h"
      
      class ColorLibraryViewModel : public QObject
      {
          Q_OBJECT
      public:
           ColorLibraryViewModel(QQmlContext* ctxt, DataSourceInterface *dataSource);
           ColorLibraryViewModel(){}
          Q_INVOKABLE void loadColorLibraries();
      
      signals:
           //void librariesLoaded();
      
      public slots:
      
      private:
           DataSourceInterface * _DataSource;
           QQmlContext * _ctxt;
           ColorLibraryListModel _colorLibraryListModel;
           void initialize();
      
      };
      
      #endif // COLORLIBRARYVIEWMODEL_H
      
      #include "colorlibraryviewmodel.h"
      #include "colorlibrariesform.h"
      #include "ColorLibraryListModel.h"
      #include "generallistitem.h"
      #include "datasourceinterface.h"
      #include <QQmlContext>
      
      ColorLibraryViewModel::ColorLibraryViewModel(QQmlContext *ctxt, DataSourceInterface *dataSource)
      {
          _DataSource = dataSource;
          _ctxt = ctxt;
          initialize();
      }
      
      void ColorLibraryViewModel::initialize()
      {
          _ctxt->setContextProperty("colorLibraryListModel", &_colorLibraryListModel);
      }
      
      void ColorLibraryViewModel::loadColorLibraries()
      {
          ColorLibrariesForm colorLibrariesForm;
          colorLibrariesForm.Initialize(_DataSource, false, false);
          QVector<GeneralListItem> m_generalListItems;
          colorLibrariesForm.GetListItems(m_generalListItems);
      
          // Clear any previously loaded data
          if(_colorLibraryListModel.rowCount() > 0)
           _colorLibraryListModel.removeRows(0, _colorLibraryListModel.rowCount());
      
      
          foreach(GeneralListItem m_generalListItem, m_generalListItems){
              QIcon type = QIcon(":Images/Images/Color_Libraries_button.png") ;
              QString name = m_generalListItem._Name;
              bool isReadOnly = m_generalListItem._IsReadOnly;
              StandardDisplayItem m_standardDisplayItem(type, name, isReadOnly);
              _colorLibraryListModel.addStandardDisplayItem(m_standardDisplayItem);
          }
      }
      

      My model which is actually bound to the ListView is defined and implemented as such:

      #ifndef COLORLIBRARYLISTMODEL_H
      #define COLORLIBRARYLISTMODEL_H
      
      #include <QObject>
      #include <QAbstractListModel>
      #include <QStringList>
      #include <StandardDisplayItem.h>
      
      
      class ColorLibraryListModel : public QAbstractListModel
      {
          Q_OBJECT
      public:
          enum ColorLibraryRoles {
              NameRole,
              TypeRole,
              IsReadOnlyRole
          };
      
          ColorLibraryListModel(QObject *parent = nullptr);
      
          void addStandardDisplayItem(const StandardDisplayItem &standardDisplayItem);
      
          void clearStandardDisplayItems(){m_standardDisplayItems.clear();}
      
          Qt::ItemFlags flags(const QModelIndex &index);
      
          int rowCount(const QModelIndex & parent = QModelIndex()) const;
      
          QVariant data(const QModelIndex & index, int role = Qt::DisplayRole) const;
      
          bool removeRows(int row, int count, const QModelIndex &parent = QModelIndex());
      
      signals:
      
      public slots:
      
      protected:
          QHash<int, QByteArray> roleNames() const;
      
      private:
          QList<StandardDisplayItem> m_standardDisplayItems;
      };
      
      #endif // COLORLIBRARYLISTMODEL_H
      
      
      #include "ColorLibraryListModel.h"
      #include <QAbstractListModel>
      
      ColorLibraryListModel::ColorLibraryListModel(QObject *parent)
          : QAbstractListModel(parent)
      {
      
      }
      
      QHash<int, QByteArray>ColorLibraryListModel::roleNames() const {
          QHash<int, QByteArray> roles;
          roles[NameRole]= "name";
          roles[TypeRole] = "type";
          roles[IsReadOnlyRole] = "isReadOnly";
          return roles;
      }
      
      void ColorLibraryListModel::addStandardDisplayItem(const StandardDisplayItem &standardDisplayItem)
      {
          beginInsertRows(QModelIndex(), rowCount(), rowCount());
          m_standardDisplayItems << standardDisplayItem;
          endInsertRows();
      }
      
      int ColorLibraryListModel::rowCount(const QModelIndex &parent) const
      {
          Q_UNUSED(parent);
          return m_standardDisplayItems.count();
      }
      
      QVariant ColorLibraryListModel::data(const QModelIndex &index, int role) const
      {
          if(!index.isValid())
              return QVariant();
          if(index.row() < 0 || index.row() >= m_standardDisplayItems.count())
              return QVariant();
      
          const StandardDisplayItem &standardDisplayItem = m_standardDisplayItems[index.row()];
          if(role == NameRole)
              return standardDisplayItem._name();
          else if(role == TypeRole)
              return standardDisplayItem._type();
          else if(role == IsReadOnlyRole)
              return standardDisplayItem._isReadOnly() ? QString("Yes") : QString("No");
          return QVariant();
      }
      
      bool ColorLibraryListModel::removeRows(int row, int count, const QModelIndex &parent)
      {
          Q_UNUSED(parent)
          beginRemoveRows(QModelIndex(), row, row+count-1);
      
          for(int currentRow=0; currentRow < count; ++currentRow) {
              m_standardDisplayItems.removeAt(currentRow);
          }
      
          endRemoveRows();
          return true;
      }
      

      The process is initiated through a main.cpp implementation as such:

      #include <QGuiApplication>
      #include <QQmlApplicationEngine>
      #include <QQmlContext>
      #include <QtQuick>
      #include "colorlibraryviewmodel.h"
      #include "ColorLibraryListModel.h"
      #include "colorlibrariesform.h"
      #include "DBsource.h"
      #include "GeneralListDetailForm.h"
      
      
      int main(int argc, char *argv[])
      {
          QCoreApplication::setAttribute(Qt::AA_EnableHighDpiScaling);
      
          QGuiApplication app(argc, argv);
      
          QQuickView view;
          view.setResizeMode(QQuickView::SizeRootObjectToView);
          QQmlContext *ctxt = view.rootContext();
      
          DBSource m_dbSource;
          ColorLibraryViewModel colorLibraryViewModel(ctxt, &m_dbSource);
      
          ctxt->setContextProperty("colorLibraryViewModel", &colorLibraryViewModel);
      
          view.setSource(QUrl("qrc:/main.qml"));
          view.show();
      
          return app.exec();
      }
      
      

      Does anyone spot the problem based on my implementation? Many thanks in advance!

      1 Reply Last reply Reply Quote 0
      • First post
        Last post