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

QTreeView crashes because it stores QModelIndexes

    XMLWordPrintable

Details

    • Bug
    • Resolution: Unresolved
    • P2: Important
    • None
    • 5.15.2, 6.0.0 RC2
    • Widgets: Itemviews
    • None
    • 6012285e7dedb4364e2db087b7d5cbfc2973320a

    Description

      QTreeView has the ridiculous idea of storing QModelIndexes to the underlying model to populate a vector of QTreeViewItem objects:

      struct QTreeViewItem
      {
          QTreeViewItem() : parentItem(-1), expanded(false), spanning(false), hasChildren(false),
                            hasMoreSiblings(false), total(0), level(0), height(0) {}
          QModelIndex index; // we remove items whenever the indexes are invalidated
          int parentItem; // parent item index in viewItems
          uint expanded : 1;
          uint spanning : 1;
          uint hasChildren : 1; // if the item has visible children (even if collapsed)
          uint hasMoreSiblings : 1;
          uint total : 28; // total number of children visible
          uint level : 16; // indentation
          int height : 16; // row height
      };
      

      Once you know this, it's super easy to build models that make QTreeView crash – just build a (tree) model for which the QModelIndexes internal pointers are not stable over time.

      ... QStandardItemModel would be a good example, but that model is broken if one removes and replaces internal nodes (QTBUG-89145). It's still easy to set it up in a crashing way, build a tree and remove a node from the middle via takeItem (QTBUG-89072). ...

      One may concoct an evil-but-technically-100%-correct model which will crash if any QModelIndex is held across event loop iterations:

      1. store a number N in the model
      2. run a QTimer with 0 interval that increments the N in the model
      3. from index()/parent()/etc., return QModelIndexes loaded with the current N
      4. in any method taking an index, check if the number in the index matches N, if not crash

      One may even concoct a less-than-evil model, that changes its model indexes only after a signal emission, and QTreeView would still break down. For isntance, tree of indivudally allocated nodes, returning QModelIndexes with pointers to the nodes. Nodes are immutable and changing a node's data means creating a new node and installing it in place of old node (and emit dataChanged() as expected). However, QTreeView::dataChanged doesn't flush its list of QModelIndex, resulting in a crash.

      Attachments

        Issue Links

          For Gerrit Dashboard: QTBUG-89146
          # Subject Branch Project Status CR V

          Activity

            People

              qt.team.quick.subscriptions Qt Quick and Widgets Team
              peppe Giuseppe D'Angelo
              Votes:
              1 Vote for this issue
              Watchers:
              5 Start watching this issue

              Dates

                Created:
                Updated:

                Gerrit Reviews

                  There is 1 open Gerrit change