拖动在“ QfileModelsystem”中不起作用
我正在尝试在qfilesystemmodel
中进行拖放行为,但是由于我没有在拖放之前的经验,所以我首先在qtreeview
上尝试了它。 (我附加了行为的视频)
现在我对自己想要的行为很好,然后我只是将模型更改为qfilesystemmodel
,但可悲的是它无法正常工作。因此,我尝试阅读 qfilesystemmodelmodelmodel
a href =“ https://doc.qt.io/qt-5/qtreeview.html” rel =“ nofollow noreferrer”> qtreeview
和 从qt
拖动并删除,我最终得到了下面的代码:
我最终得到的代码:
import os
import sys
from PyQt5.QtCore import *
from PyQt5.QtWidgets import *
from PyQt5.QtGui import *
class MQTreeView(QTreeView):
def __init__(self, model):
super().__init__()
self.setSelectionMode(QAbstractItemView.ExtendedSelection)
# self.setDragDropMode(QAbstractItemView.InternalMove)
self.setModel(model)
self.setDragDropMode(QAbstractItemView.DragDrop)
self.setRootIndex(model.index(os.path.dirname(os.path.abspath("__file__"))))
self.setDefaultDropAction(Qt.MoveAction)
self.viewport().setAcceptDrops(True)
def dragEnterEvent(self, event):
m = event.mimeData()
if m.hasUrls():
event.accept()
return
event.ignore()
# return super().dragEnterEvent(event)
def dropEvent(self, event):
print("[drop event] - dropped")
if event.source():
QTreeView.dropEvent(self, event)
else:
ix = self.indexAt(event.pos())
model = self.model()
if ix.isValid():
if not model.isDir(ix):
ix = ix.parent() # In case of folder/Dir
pathDir = model.filePath(ix)
else:
# for empty drag and drop
pathDir = model.rootPath()
m = event.mimeData()
if m.hasUrls():
urlLocals = [url for url in m.urls() if url.isLocalFile()]
accepted = False
for urlLocal in urlLocals:
path = urlLocal.toLocalFile()
info = QFileInfo(path)
n_path = QDir(pathDir).filePath(info.fileName())
o_path = info.absoluteFilePath()
if n_path == o_path:
continue
if info.isDir():
QDir().rename(o_path, n_path)
else:
qfile = QFile(o_path)
if QFile(n_path).exists():
n_path += "(copy)"
qfile.rename(n_path)
print(f"added -> {info.fileName()}")
accepted = True
if accepted:
event.acceptProposedAction()
# return super().dropEvent(event)
class AppDemo(QWidget):
def __init__(self):
super().__init__()
# -- right -- #
self.model1 = QFileSystemModel()
self.model1.setRootPath(os.path.dirname(os.path.abspath("__file__")))
self.view1 = MQTreeView(self.model1)
# -- left -- #
self.model2 = QFileSystemModel()
self.model2.setRootPath(os.path.dirname(os.path.abspath("__file__")))
self.view2 = MQTreeView(self.model2)
# -- layout -- #
layout = QHBoxLayout(self)
layout.addWidget(self.view1)
layout.addWidget(self.view2)
app = QApplication(sys.argv)
main = AppDemo()
main.show()
app.exec_()
上面的代码仍未执行我想要的行为,但我很确定其他问题是错误的,并且没有覆盖功能(dragenterevent
和dropevent
)。我最好的猜测是,我没有正确地设置正确的方法QTREEVIEW
接受下降,尽管我不确定。
我的问题:我的实施是什么问题?是我接受下降还是其他的方式?
I'm trying to make a drag and drop behavior in QFileSystemModel
but because I have no experience in making a drag and drop before, I tried it first on QTreeView
. (I attached the video of the behavior)
Now that I'm fine with the behavior I want, I then just changed the model to QFileSystemModel
but sadly It's not working. So I tried to read the QFileSystemModel
, QTreeView
, and Drag and Drop from Qt
and I ended up with the code below:
The code I ended up with:
import os
import sys
from PyQt5.QtCore import *
from PyQt5.QtWidgets import *
from PyQt5.QtGui import *
class MQTreeView(QTreeView):
def __init__(self, model):
super().__init__()
self.setSelectionMode(QAbstractItemView.ExtendedSelection)
# self.setDragDropMode(QAbstractItemView.InternalMove)
self.setModel(model)
self.setDragDropMode(QAbstractItemView.DragDrop)
self.setRootIndex(model.index(os.path.dirname(os.path.abspath("__file__"))))
self.setDefaultDropAction(Qt.MoveAction)
self.viewport().setAcceptDrops(True)
def dragEnterEvent(self, event):
m = event.mimeData()
if m.hasUrls():
event.accept()
return
event.ignore()
# return super().dragEnterEvent(event)
def dropEvent(self, event):
print("[drop event] - dropped")
if event.source():
QTreeView.dropEvent(self, event)
else:
ix = self.indexAt(event.pos())
model = self.model()
if ix.isValid():
if not model.isDir(ix):
ix = ix.parent() # In case of folder/Dir
pathDir = model.filePath(ix)
else:
# for empty drag and drop
pathDir = model.rootPath()
m = event.mimeData()
if m.hasUrls():
urlLocals = [url for url in m.urls() if url.isLocalFile()]
accepted = False
for urlLocal in urlLocals:
path = urlLocal.toLocalFile()
info = QFileInfo(path)
n_path = QDir(pathDir).filePath(info.fileName())
o_path = info.absoluteFilePath()
if n_path == o_path:
continue
if info.isDir():
QDir().rename(o_path, n_path)
else:
qfile = QFile(o_path)
if QFile(n_path).exists():
n_path += "(copy)"
qfile.rename(n_path)
print(f"added -> {info.fileName()}")
accepted = True
if accepted:
event.acceptProposedAction()
# return super().dropEvent(event)
class AppDemo(QWidget):
def __init__(self):
super().__init__()
# -- right -- #
self.model1 = QFileSystemModel()
self.model1.setRootPath(os.path.dirname(os.path.abspath("__file__")))
self.view1 = MQTreeView(self.model1)
# -- left -- #
self.model2 = QFileSystemModel()
self.model2.setRootPath(os.path.dirname(os.path.abspath("__file__")))
self.view2 = MQTreeView(self.model2)
# -- layout -- #
layout = QHBoxLayout(self)
layout.addWidget(self.view1)
layout.addWidget(self.view2)
app = QApplication(sys.argv)
main = AppDemo()
main.show()
app.exec_()
The code above is still not doing the behavior I want but I'm pretty sure that something else is wrong and it is not with the overridden function (dragEnterEvent
and dropEvent
). My best guess is that I didn't set properly the correct way QTreeView
accepts the drops although I'm not really sure.
My Question: What is wrong with my Implementation? Is it the way I accept drops or it is something else?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
找到了什么问题!我没有覆盖
dragMoveEvent
方法。我需要覆盖dragMoveEvent
以确保不会禁止阻力。我需要在
dragenterevent
中接受所有拖动事件:然后,我需要过滤
dragmoveevent
中的事件:我附加了下面的工作行为的视频和代码。
最终实现:
Found what's wrong! I didn't override the
dragMoveEvent
method. I need to override thedragMoveEvent
to make sure that the drag will not be forbidden.I need to accept all drag event in the
dragEnterEvent
:Then I need to filter the events in the
dragMoveEvent
:I attached the video and code of the working behavior below.
The final implementation: