可重新排序的列表视图不调用removeRows()

时间:2020-06-03 17:25:46

标签: python pyqt pyqt5 qlistview qabstractlistmodel

我正在尝试实现一个列表视图,该列表视图能够执行内部移动(MoveAction)并接受来自外部的拖放操作(CopyAction)。

我已经读过一些站点,如果我们dropMimeData()返回True到QtCore.Qt.MoveAction,则Qt将调用removeRows()。 但是,在下面概述我的代码的情况下,永远不会打印“ removeRows()被调用”。

我自己不能在dropMimeData()中调用它,因为我不知道应该删除哪个索引。 (而且我认为您不应该自己做)

此外,我看到的问题是,将其移至其原始索引之前或之后的条目。 (之前=我们现在需要删除旧索引加1)

class ToolListModel(QtCore.QAbstractListModel):
    def __init__(self, tabText):
        super(ToolListModel, self).__init__()
        self.tabText = tabText

        #integrity check
        jsonConfigHelper.validateBookmark_data()
        self.modelData = jsonConfigHelper.getBookmark_data().get(self.tabText)

    def writeTabToJSON(self):
        data = jsonConfigHelper.getBookmark_data()
        data[self.tabText] = self.modelData
        jsonConfigHelper.overrideBookmark_data(data)


    # Returns the list of allowed MIME types
    def mimeTypes(self):
        return [ "application/x-commander"]


    # Returns an object that contains serialized items of data corresponding to the list of indexes specified. 
    # The format used to describe the encoded data is obtained from the mimeTypes() function
    def mimeData(self, indices):
        mimeData = QtCore.QMimeData()
        #data to bytes

        encodedData = QtCore.QByteArray(indices[0].data(99).get(TOKENS.FUNCTION_LABEL).encode('utf-8'))

        mimeData.setData("application/x-commander", encodedData)
        print(mimeData)
        return mimeData

    def dropMimeData(self, mimeData, action, row, column, parent):
        if self.canDropMimeData(mimeData, action, row, column, parent) == False:
            return False
        else:
            encodedData = mimeData.data("application/x-commander")
            decodedData = encodedData.data().decode()

            #look for precofigured shortname if none found leave empty
            shortname = globalVars.DATA.get(decodedData).get(TOKENS.FUNCTION_SHORTNAME, "none")

            tempDict = {
                TOKENS.FUNCTION_LABEL : decodedData, 
                TOKENS.FUNCTION_SHORTNAME : shortname
            }

            if action == QtCore.Qt.CopyAction:
                print ("Copying")
                # inserting 'count' empty rows starting at 'row'
                self.insertRows(row, 1, QtCore.QModelIndex())
                idx = self.index(row, 0, QtCore.QModelIndex())
                self.setData(idx, tempDict)
                return True

            if action == QtCore.Qt.MoveAction:
                print ("Moving")
                self.insertRows(row, 1, QtCore.QModelIndex())
                idx = self.index(row, 0, QtCore.QModelIndex())
                self.setData(idx, tempDict)
                # remove calling
                return True

    def setData(self, index, value, role=QtCore.Qt.EditRole):

        print("setData() called")
        self.modelData[index.row()] = value
        self.dataChanged.emit(index, index)
        self.writeTabToJSON()
        return True


    def insertRows(self, row, count, parent):

        print("insertRows() called")
        self.beginInsertRows(QtCore.QModelIndex(), row, row + count - 1)
        for i in range(0, count):
            print(i)
            self.modelData.insert(row + i, dict())
        self.endInsertRows()
        return True

    def removeRows(self, row, count, parent):

        print("removeRows() called")
        self.beginRemoveRows(QtCore.QModelIndex(), row, row + count - 1)
        for i in range(count, 0, -1):
            print(i)
            self.modelData.pop(row - i + 1)
        self.endRemoveRows()
        self.writeTabToJSON()
        return True

    def canDropMimeData(self, mimeData, action, row, column, parent):
        if mimeData.hasFormat("application/x-commander") != True:
            return False
        if action != QtCore.Qt.MoveAction and action != QtCore.Qt.CopyAction :
            return False
        if column > 0: 
            return False

        return True

    def supportedDropActions(self):
        return QtCore.Qt.MoveAction | QtCore.Qt.CopyAction        

    # moves count rows starting with the given sourceRow under parent sourceParent to row destinationChild under parent destinationParent.
    def moveRows(self, sourceParent, sourceRow, count, destinationParent, destinationChild):
        self.beginMoveRows(sourceParent, sourceRow, sourceRow + count -1, destinationParent, destinationChild)
        self.modelData.insert(destinationChild, self.modelData.pop(sourceRow))
        self.endMoveRows()

    def flags(self, index):
        if not index.isValid():
            return QtCore.Qt.ItemIsEnabled | QtCore.Qt.ItemIsDropEnabled
        return QtCore.Qt.ItemIsEnabled | QtCore.Qt.ItemIsDragEnabled | QtCore.Qt.ItemIsSelectable 

这是我自定义ListView中创建拖动的方法

def mouseMoveEvent(self, event):
    if event.buttons() != QtCore.Qt.LeftButton:
        return
    if (event.pos() - self.dragRelPos).manhattanLength() < QtWidgets.QApplication.startDragDistance():
        return

    vpos = self.viewport().mapFromGlobal(self.dragGlobPos)
    index = self.indexAt(vpos)
    row = index.row()
    col = index.column()

    if not index.isValid(): # don't acc
        return
    else:
        dragObj = QtGui.QDrag(self)
        mimeData = self.model().mimeData([index])
        dragObj.setMimeData(mimeData)
        dragObj.exec_(QtCore.Qt.MoveAction)

0 个答案:

没有答案