我正在尝试实现一个列表视图,该列表视图能够执行内部移动(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)