Uploaded image for project: 'Qt'
  1. Qt
  2. QTBUG-81976

ListView delegates produces "TypeError: Cannot read property 'width' of null" when removing item from QAbstractItemModel

    XMLWordPrintable

    Details

    • Commits:
      5445fcac36d7122d533a2bdf0fcfe6206b7f3ff4 (qt/qtdeclarative/5.15)

      Description

      The following code worked in 5.14.1, but now produces an error in 5.15.

      main.cpp
      #include <QGuiApplication>
      #include <QQmlApplicationEngine>
      #include <QAbstractListModel>
      #include <QQmlContext>
      #include <QKeyEvent>
      #include <QDebug>
      #include <QAbstractListModel>
      
      class BattleQueueModel : public QAbstractListModel
      {
          Q_OBJECT
      
      public:
          enum {
              NameRole = Qt::UserRole
          };
      
          explicit BattleQueueModel(QObject *parent = nullptr);
      
          int rowCount(const QModelIndex &parent = QModelIndex()) const override;
          QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const override;
          QHash<int, QByteArray> roleNames() const override;
      
      public slots:
          void pop();
      
      private:
          QVector<QString> mData;
      };
      
      BattleQueueModel::BattleQueueModel(QObject *parent) :
          QAbstractListModel(parent)
      {
          mData.fill(QLatin1String("Test"), 10);
      }
      
      int BattleQueueModel::rowCount(const QModelIndex &) const
      {
          return mData.size();
      }
      
      QVariant BattleQueueModel::data(const QModelIndex &index, int role) const
      {
          if (index.row() < 0 || index.row() >= rowCount()) {
              return QVariant();
          }
      
          qDebug() << "data() called with index" << index << "and role" << role;
          switch (role) {
          case NameRole:
          case Qt::DisplayRole:
              return mData.at(index.row());
          }
      
          return QVariant();
      }
      
      QHash<int, QByteArray> BattleQueueModel::roleNames() const
      {
          QHash<int, QByteArray> names;
          names[NameRole] = "name";
          return names;
      }
      
      void BattleQueueModel::pop()
      {
          if (mData.isEmpty())
              return;
      
          qDebug() << "about to call beginRemoveRows";
          beginRemoveRows(QModelIndex(), mData.size() - 1, mData.size() - 1);
          qDebug() << "called beginRemoveRows";
      
          mData.pop_back();
      
          qDebug() << "about to call endRemoveRows";
          endRemoveRows();
          qDebug() << "called endRemoveRows";
      }
      
      int main(int argc, char *argv[])
      {
          QCoreApplication::setAttribute(Qt::AA_EnableHighDpiScaling);
      
          QGuiApplication app(argc, argv);
      
          QQmlApplicationEngine engine;
      
      //    EventFilter filter;
      //    app.installEventFilter(&filter);
      
          qmlRegisterType<BattleQueueModel>("App", 1, 0, "BattleQueueModel");
      
          const QUrl url(QStringLiteral("qrc:/main.qml"));
          QObject::connect(&engine, &QQmlApplicationEngine::objectCreated,
                           &app, [url](QObject *obj, const QUrl &objUrl) {
              if (!obj && url == objUrl)
                  QCoreApplication::exit(-1);
          }, Qt::QueuedConnection);
          engine.load(url);
      
          return app.exec();
      }
      
      #include "main.moc"
      
      main.qml
      import QtQuick 2.14
      import QtQuick.Layouts 1.14
      import QtQuick.Controls 2.14
      
      import App 1.0
      
      ApplicationWindow {
          id: window
          width: 400
          height: 400
          visible: true
      
          ListView {
              id: battleListView
              anchors.fill: parent
      
              model: BattleQueueModel {
                  id: abilityModel
              }
      
              delegate: Text {
                  text: model.name + index
                  width: parent.width
              }
      
              Timer {
                  running: true
                  repeat: true
                  interval: 1000
                  onTriggered: {
                      battleListView.model.pop()
                  }
              }
          }
      }
      

        Attachments

          Issue Links

          No reviews matched the request. Check your Options in the drop-down menu of this sections header.

            Activity

              People

              Assignee:
              richard Richard Moe Gustavsen
              Reporter:
              mitch_curtis Mitch Curtis
              Votes:
              0 Vote for this issue
              Watchers:
              3 Start watching this issue

                Dates

                Created:
                Updated:
                Resolved:

                  Gerrit Reviews

                  There are no open Gerrit changes