问题描述
在 PyQt 4 中,我想创建一个 QTreeView,可以通过拖放操作重新组织其结构.
In PyQt 4 I would like to create a QTreeView with possibility to reorganize its structure with drag and drop manipulation.
我已经为 QTreeView 实现了自己的模型(QAbstractItemModel),因此我的 QTreeView 可以正确显示数据.现在我想添加对树节点的拖放支持,以便能够将树内的节点从一个父节点移动到另一个父节点,拖放复制等等,但我找不到任何完整的教程来实现这一点.我找到了一些关于 QTreeWidget 的教程和提示,但没有找到带有自定义模型的 QTreeView.有人能指点我在哪里看吗?
I have implemented my own model(QAbstractItemModel) for QTreeView so my QTreeView properly displays the data. Now I would like to add drag and drop support for tree's nodes to be able to move a node inside the tree from one parent to another one, drag-copy and so on, but I cannot find any complete tutorial how to achieve this. I have found few tutorials and hints for QTreeWidget, but not for QTreeView with custom model. Can someone point me where to look?
谢谢.
推荐答案
您可以通过将 QtGui.QAbstractItemView.InternalMove 设置为 dragDropMode 属性树视图控件.另请查看此处的文档 使用拖动&与项目视图一起丢弃.下面是一个为其项目启用内部拖放的树视图的小示例.
You can enable drag and drop support for tree view items by setting QtGui.QAbstractItemView.InternalMove into the dragDropMode property of the treeview control. Also take a look at the documentation here Using drag & drop with item views. Below is a small example of a treeview with internal drag and drop enabled for its items.
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:树视图+抽象模型,支持拖放
Edit0: treeview + abstract model with drag and drop support
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()
希望这会有所帮助,问候
hope this helps, regards