Hello.
WorkFlow:
[QAbstractTableModel]<===>[QtableView]
Vertical Header is moveable, and when the user enacts such functionality, the following is called (from QtableView):
self.tableView.verticalHeader().setMovable(True)
self.tableView.verticalHeader().sectionMoved.connect(self.rowsChanged)
...
def rowsChanged(self,dataRow,oldDisplayRow,newDisplayRow):
self.tableData.resortRows(dataRow,oldDisplayRow,newDisplayRow)
self.tableView.verticalHeader().setMovable(True)
self.tableView.verticalHeader().sectionMoved.connect(self.rowsChanged)
...
def rowsChanged(self,dataRow,oldDisplayRow,newDisplayRow):
self.tableData.resortRows(dataRow,oldDisplayRow,newDisplayRow)
To copy to clipboard, switch view to plain text mode
QAbstractTableModel catches the call, and enacts the following:
def resortRows(self,dataRow,oldDisplayRow,newDisplayRow):
print "you moved dataRow %s from displayRow %s to displayRow %s" % (dataRow,oldDisplayRow,newDisplayRow)
self.rows.insert(newDisplayRow,self.rows.pop(dataRow))
self.layoutChanged.emit()
def resortRows(self,dataRow,oldDisplayRow,newDisplayRow):
print "you moved dataRow %s from displayRow %s to displayRow %s" % (dataRow,oldDisplayRow,newDisplayRow)
self.rows.insert(newDisplayRow,self.rows.pop(dataRow))
self.layoutChanged.emit()
To copy to clipboard, switch view to plain text mode
While the underlying data structure (self.rows) is properly rearranged, the QtableView does not reflect these changes - and rather exhibits random offsetting of rows; non-synchronous with the ACTUAL changes made.
Are the 'beginInsertRows(...)/endInstertRows()' and 'beginRemoveRows(...)/endRemoveRows()' nessecary?
As when I implement these as follows, neither the QtableView, nor the underlying data (self.rows) is properly altered:
def resortRows(self,dataRow,oldDisplayRow,newDisplayRow):
print "you moved dataRow %s from displayRow %s to displayRow %s" % (dataRow,oldDisplayRow,newDisplayRow)
self.
beginInsertRows(QtCore.
QModelIndex(),newDisplayRow,newDisplayRow
) self.rows.insert(newDisplayRow,self.rows[dataRow])
self.endInsertRows()
self.
beginRemoveRows(QtCore.
QModelIndex(),dataRow,dataRow
) self.rows.pop(dataRow)
self.endRemoveRows()
def resortRows(self,dataRow,oldDisplayRow,newDisplayRow):
print "you moved dataRow %s from displayRow %s to displayRow %s" % (dataRow,oldDisplayRow,newDisplayRow)
self.beginInsertRows(QtCore.QModelIndex(),newDisplayRow,newDisplayRow)
self.rows.insert(newDisplayRow,self.rows[dataRow])
self.endInsertRows()
self.beginRemoveRows(QtCore.QModelIndex(),dataRow,dataRow)
self.rows.pop(dataRow)
self.endRemoveRows()
To copy to clipboard, switch view to plain text mode
A billion thanks!
Added after 23 minutes:
Doh!
Not yet sure if this is the most elegant manner, but implementing the following in QAbstractModel solved the problems (for now):
def resortRows(self,dataRow,oldDisplayRow,newDisplayRow):
print "you moved dataRow %s from displayRow %s to displayRow %s" % (dataRow,oldDisplayRow,newDisplayRow)
cacheData = self.rows[dataRow]
self.removeRows(dataRow)
self.
beginInsertRows(QtCore.
QModelIndex(),newDisplayRow,newDisplayRow
) self.rows.insert(newDisplayRow,cacheData)
self.endInsertRows()
def resortRows(self,dataRow,oldDisplayRow,newDisplayRow):
print "you moved dataRow %s from displayRow %s to displayRow %s" % (dataRow,oldDisplayRow,newDisplayRow)
cacheData = self.rows[dataRow]
self.removeRows(dataRow)
self.beginInsertRows(QtCore.QModelIndex(),newDisplayRow,newDisplayRow)
self.rows.insert(newDisplayRow,cacheData)
self.endInsertRows()
To copy to clipboard, switch view to plain text mode
# removes row from model (only if entire row-children are selected)
def removeRows(self, row):
self.rows.pop(int(row))
self.endRemoveRows()
# removes row from model (only if entire row-children are selected)
def removeRows(self, row):
self.beginRemoveRows(QtCore.QModelIndex(),row,row)
self.rows.pop(int(row))
self.endRemoveRows()
To copy to clipboard, switch view to plain text mode
Bookmarks