Python PyQt中具有拖放支持的QTreeView
在pyqt4中,我想创建一个QTreeView,可以通过拖放操作重新组织其结构 我已经为QTreeView实现了我自己的模型(qabstractemmodel),因此我的QTreeView可以正确地显示数据。 现在,我想添加对树节点的拖放支持,以便能够将树中的节点从一个父节点移动到另一个父节点,拖动副本等,但我找不到任何完整的教程来实现这一点。我发现了一些关于QTreeWidget的教程和提示,但对于具有自定义模型的QTreeView却没有。 有人能指给我看哪里吗Python PyQt中具有拖放支持的QTreeView,python,drag-and-drop,pyqt,qtreeview,Python,Drag And Drop,Pyqt,Qtreeview,在pyqt4中,我想创建一个QTreeView,可以通过拖放操作重新组织其结构 我已经为QTreeView实现了我自己的模型(qabstractemmodel),因此我的QTreeView可以正确地显示数据。 现在,我想添加对树节点的拖放支持,以便能够将树中的节点从一个父节点移动到另一个父节点,拖动副本等,但我找不到任何完整的教程来实现这一点。我发现了一些关于QTreeWidget的教程和提示,但对于具有自定义模型的QTreeView却没有。 有人能指给我看哪里吗 谢谢。通过将QtGui.qab
谢谢。通过将QtGui.qabstractemview.InternalMove设置为treeview控件的属性,可以启用对树视图项目的拖放支持。还可以查看此处的文档。下面是treeview的一个小示例,它的项目启用了内部拖放功能
import sys
from PyQt4 import QtGui, QtCore
class MainForm(QtGui.QMainWindow):
def __init__(self, parent=None):
super(MainForm, self).__init__(parent)
self.model = QtGui.QStandardItemModel()
for k in range(0, 4):
parentItem = self.model.invisibleRootItem()
for i in range(0, 4):
item = QtGui.QStandardItem(QtCore.QString("item %0 %1").arg(k).arg(i))
parentItem.appendRow(item)
parentItem = item
self.view = QtGui.QTreeView()
self.view.setModel(self.model)
self.view.setDragDropMode(QtGui.QAbstractItemView.InternalMove)
self.setCentralWidget(self.view)
def main():
app = QtGui.QApplication(sys.argv)
form = MainForm()
form.show()
app.exec_()
if __name__ == '__main__':
main()
Edit0:具有拖放支持的treeview+抽象模型
import sys
from PyQt4 import QtGui, QtCore
class TreeModel(QtCore.QAbstractItemModel):
def __init__(self):
QtCore.QAbstractItemModel.__init__(self)
self.nodes = ['node0', 'node1', 'node2']
def index(self, row, column, parent):
return self.createIndex(row, column, self.nodes[row])
def parent(self, index):
return QtCore.QModelIndex()
def rowCount(self, index):
if index.internalPointer() in self.nodes:
return 0
return len(self.nodes)
def columnCount(self, index):
return 1
def data(self, index, role):
if role == 0:
return index.internalPointer()
else:
return None
def supportedDropActions(self):
return QtCore.Qt.CopyAction | QtCore.Qt.MoveAction
def flags(self, index):
if not index.isValid():
return QtCore.Qt.ItemIsEnabled
return QtCore.Qt.ItemIsEnabled | QtCore.Qt.ItemIsSelectable | \
QtCore.Qt.ItemIsDragEnabled | QtCore.Qt.ItemIsDropEnabled
def mimeTypes(self):
return ['text/xml']
def mimeData(self, indexes):
mimedata = QtCore.QMimeData()
mimedata.setData('text/xml', 'mimeData')
return mimedata
def dropMimeData(self, data, action, row, column, parent):
print 'dropMimeData %s %s %s %s' % (data.data('text/xml'), action, row, parent)
return True
class MainForm(QtGui.QMainWindow):
def __init__(self, parent=None):
super(MainForm, self).__init__(parent)
self.treeModel = TreeModel()
self.view = QtGui.QTreeView()
self.view.setModel(self.treeModel)
self.view.setDragDropMode(QtGui.QAbstractItemView.InternalMove)
self.setCentralWidget(self.view)
def main():
app = QtGui.QApplication(sys.argv)
form = MainForm()
form.show()
app.exec_()
if __name__ == '__main__':
main()
希望这对您有所帮助,谢谢您的回答。但这并不能解决我的问题。我知道使用QStandardItemModel+QStandardItem可以像预期的那样工作。但我需要使用自定义模型,即来自QabstracteModel的纯子类使其工作。我认为我需要在模型中实现一些方法,或者对树项使用一些专门的对象。现在,即使设置为显示拖放指示器,拖放也不会显示。。。很明显,我只是遗漏了一些东西。我还有一点意见。如果以PyQt标准示例中的“simpletreemodel”为例:如何向其添加拖放支持?如果我只是添加setAcceptsDrop(True)、setDragEnabled(True)、setDragDropMode(view.InternalMove)来查看和标记ItemsDragEnabled | ItemsDragEnabled to model,那么仅仅具备拖放功能是不够的;但请记住,QT是开源的,所以您可以随时查看QStandardItemModel内部的情况,QStandardItemModel是qabstractemmodel的后代,支持拖放。我已经用简单的抽象模型示例编辑了我的文章,它应该支持拖放。是的,它现在可以工作了!你不知道我有多想谢谢你。非常感谢。我发现python3内部的PyQt中不存在QString。我读了这篇文章,为我解决了这个问题: