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

Incorrect column width and selection when moving columns in QTableView (QAbstractTableModel) using beginMoveColumns

    XMLWordPrintable

    Details

    • Type: Bug
    • Status: Reported
    • Priority: P2: Important
    • Resolution: Unresolved
    • Affects Version/s: 5.13.0, 5.13.1, 5.13.2, 5.14.1, 5.14.2, 5.15.0, 5.15.1, 5.15.2, 5.15.3, 5.15.4
    • Fix Version/s: None
    • Component/s: Widgets: Itemviews
    • Labels:
      None

      Description

      I am using beginMoveColumns to move a single column over in a QTableView, but cell selections get shuffled and column widths don't move correctly. Moving rows using the same logic seems to work fine. 

      Video: https://www.screencast.com/t/5UJ0iByZCEE

      Below is a PyQt5 example in Python, I don't use C++ but maybe someone else can replicate it since I don't think this is a problem with the Python wrapper

      from PyQt5 import QtWidgets, QtCore, QtGui
      import sys
      from PyQt5.QtCore import QModelIndex, Qt
      
      
      class MyTableModel(QtCore.QAbstractTableModel):
          def __init__(self, data=[[]], parent=None):
              super().__init__(parent)
              self.data = data
      
          def headerData(self, section: int, orientation: Qt.Orientation, role: int):
              if role == QtCore.Qt.DisplayRole:
                  return "Header"
      
          def columnCount(self, parent=None):
              return len(self.data[0])
      
          def rowCount(self, parent=None):
              return len(self.data)
      
          def data(self, index: QModelIndex, role: int):
              if role == QtCore.Qt.DisplayRole:
                  row = index.row()
                  col = index.column()
                  return str(self.data[row][col])
      
          def move_column(self, ix, new_ix):
              parent = QtCore.QModelIndex()
              if new_ix > ix:
                  target = new_ix + 1
              else:
                  target = new_ix
              self.beginMoveColumns(parent, ix, ix, parent, target)
      
              # Shift column in each row
              for row in self.data:
                  row.insert(new_ix, row.pop(ix))
      
              self.endMoveColumns()
      
          def move_row(self, ix, new_ix):
              parent = QtCore.QModelIndex()
              if new_ix > ix:
                  target = new_ix + 1
              else:
                  target = new_ix
              self.beginMoveRows(parent, ix, ix, parent, target)
      
              # Shift row
              self.data.insert(new_ix, self.data.pop(ix))
      
              self.endMoveRows()
      
      
      if __name__ == '__main__':
          app = QtWidgets.QApplication(sys.argv)
      
          data = []
          for i in range(12):
              row = []
              data.append(row)
              for j in range(6):
                  row.append(f"R{i}_C{j}")
      
          model = MyTableModel(data)
          view = QtWidgets.QTableView()
          view.setModel(model)
      
          view.setColumnWidth(0, 50)
          view.setColumnWidth(1, 100)
      
          view.setRowHeight(0, 50)
          view.setRowHeight(1, 100)
      
          container = QtWidgets.QWidget()
          layout = QtWidgets.QVBoxLayout()
          container.setLayout(layout)
      
          layout.addWidget(view)
      
          button = QtWidgets.QPushButton("Move 1st column right by 1")
          button.clicked.connect(lambda: model.move_column(0, 1))
          layout.addWidget(button)
      
          button = QtWidgets.QPushButton("Move 1st column right by 2")
          button.clicked.connect(lambda: model.move_column(0, 2))
          layout.addWidget(button)
      
          button = QtWidgets.QPushButton("Move 1st row down by 1")
          button.clicked.connect(lambda: model.move_row(0, 1))
          layout.addWidget(button)
      
          button = QtWidgets.QPushButton("Move 1st row down by 2")
          button.clicked.connect(lambda: model.move_row(0, 2))
          layout.addWidget(button)
      
          container.resize(800, 800)
          container.show()
      
      
          sys.exit(app.exec_())
      

       

      All the versions listed below which I tested have cell selections not moving properly when moving columns, and every version EXCEPT 5.14.1 has column widths not being maintained properly when moving. In every version, moving rows with the same technique works fine.

      5.13.2: https://www.screencast.com/t/mPXbeA8Rjp
      5.14.1: https://www.screencast.com/t/d8lRFMuM04HJ
      5.14.2: https://www.screencast.com/t/n1HXqvzr
      5.15.2: https://www.screencast.com/t/kKAL4xiJJXuk
      5.15.4: https://www.screencast.com/t/smLdJb8Tb

        Attachments

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

          Activity

            People

            Assignee:
            qt.team.quick.subscriptions Qt Quick and Widgets Team
            Reporter:
            esor Adam Rose
            Votes:
            0 Vote for this issue
            Watchers:
            1 Start watching this issue

              Dates

              Created:
              Updated:

                Gerrit Reviews

                There are no open Gerrit changes