0

I have a QTable Widget of one column populated with several rows, and I would like to be able to drag and drop so i can re order them. I am able to do setDragDropMode with Internal Move, but when i move cell (0,1) to (0,3) the (0,3) get the text correctly, but cell (0,1) is now empty. I would like to swap the text of the cell when I drop it.

class myList(QtGui.QTableWidget):
    def __init__(self,parent):
        super(myList,self).__init__(parent)
#        self.setAcceptDrops(True)
        self.setDragDropMode(QtGui.QAbstractItemView.InternalMove)
FabienAndre
  • 4,514
  • 25
  • 38
pelos
  • 1,744
  • 4
  • 24
  • 34

1 Answers1

0

You can override the dropEvent callback to alter the default action. Here is a first version that writes the value in both cells.

class TableSwitcher(QtGui.QTableWidget):
    def dropEvent(self, dropEvent):
        item_src = self.selectedItems()[0]
        item_dest = self.itemAt(dropEvent.pos())
        src_value = item_src.text()
        item_src.setText(item_dest.text())
        item_dest.setText(src_value)

You can also let Qt performs the default behavior (move the dragged QTableWidgetItem, and delete the one you drop on) through super call , here you face the challenge that the default action will alter the state of widgets.

class TableSwitcher(QtGui.QTableWidget):
    def dropEvent(self, dropEvent):
        item_src = self.selectedItems()[0]
        item_dest = self.itemAt(dropEvent.pos())
        src_row = item_src.row()
        src_col = item_src.column()
        dest_value = item_dest.text()
        super(TableSwitcher,self).dropEvent(dropEvent)
        self.setItem(src_row,src_col, QtGui.QTableWidgetItem(dest_value))

Here is an example code using this class.

app = QtGui.QApplication(sys.argv)
table = TableSwitcher()
n = 5
table.setRowCount(n)
table.setColumnCount(1)
table.setDragDropMode(QtGui.QAbstractItemView.InternalMove)

for i in range(n):
        table.setItem(i,0,QtGui.QTableWidgetItem(str(i)))

table.show()
app.exec_()
FabienAndre
  • 4,514
  • 25
  • 38