I'm creating a widget to explore and manage files inside my qt application. To construct that, I'm using a QFileSystemModel
and a QListView
with the IconMode
view mode.
It should allow moving files (items) into folders (other items) with the QListView
.
My question is how do I implement this?
First, I'm trying to override the supportedDragActions
and supportedDropActions
functions from ContentFileSystemModel
to allow Move and Copy actions. Also, I override the flags
function to enable drag and drop. Finally, I override the canDropMimeData
and dropMimeData
to check if they are running, but it looks like they are not.
The first problem is that the model does not allow to drop an item file into the QListView
area once it displays a prohibited icon in the cursor (shown in the image below).
First, I have to set the model to allow the drops of items in folders. After that, I can implement the code to transfer the dragged items into the folder.
Code ready to reproduce the problem:
import sys
import os
from PySide2.QtWidgets import *
from PySide2.QtGui import *
from PySide2.QtCore import *
class ContentFileSystemModel(QFileSystemModel):
def __init__(self):
super(ContentFileSystemModel, self).__init__()
def supportedDragActions(self) -> Qt.DropActions:
print("supportedDragActions")
return Qt.MoveAction | super(ContentFileSystemModel, self).supportedDragActions() | Qt.CopyAction
def supportedDropActions(self) -> Qt.DropActions:
print("supportedDropActions")
return Qt.MoveAction | super(ContentFileSystemModel, self).supportedDropActions() | Qt.CopyAction
def flags(self, index: QModelIndex) -> Qt.ItemFlags:
defaultFlags = super(ContentFileSystemModel, self).flags(index)
if not index.isValid():
return defaultFlags
fileInfo = self.fileInfo(index)
# The target
if fileInfo.isDir():
# Allowed drop
return Qt.ItemIsDropEnabled | Qt.ItemIsDragEnabled | defaultFlags
# The source: should be directory( in that case)
elif fileInfo.isFile():
# Allowed drag
return Qt.ItemIsDropEnabled | Qt.ItemIsDragEnabled | defaultFlags
return defaultFlags
def canDropMimeData(self, data: QMimeData, action: Qt.DropAction,
row: int, column: int, parent: QModelIndex) -> bool:
print("canDropMimeData")
return True
def dropMimeData(self, data: QMimeData, action: Qt.DropAction,
row: int, column: int, parent: QModelIndex) -> bool:
print("dropMimeData")
return True
def main(argv):
app = QApplication(sys.argv)
path = "C:\\Users\\Me\\Desktop"
file_system_model = ContentFileSystemModel()
file_system_model.setRootPath(path)
file_system_model.setReadOnly(False)
lv_file_manager = QListView()
lv_file_manager.setModel(file_system_model)
lv_file_manager.setViewMode(QListView.IconMode)
lv_file_manager.setRootIndex(file_system_model.index(path))
lv_file_manager.setResizeMode(QListView.Adjust)
lv_file_manager.setMovement(QListView.Static)
lv_file_manager.setSelectionMode(QAbstractItemView.ExtendedSelection)
lv_file_manager.setWrapping(True)
lv_file_manager.setAcceptDrops(True)
lv_file_manager.setDragEnabled(True)
lv_file_manager.setDropIndicatorShown(True)
lv_file_manager.setUniformItemSizes(True)
lv_file_manager.setDragDropMode(QAbstractItemView.InternalMove)
lv_file_manager.setFlow(QListView.LeftToRight)
lv_file_manager.show()
app.exec_()
if __name__ == "__main__":
main(sys.argv)