QTreeView在PyQt中的拖放支持

问题描述:

在PyQt 4中,我想创建一个QTreeView,可以通过拖放操作来重新组织它的结构。QTreeView在PyQt中的拖放支持

我已经实现了我自己的QTreeView模型(QAbstractItemModel),所以我的QTreeView正确显示数据。 现在我想添加对树节点的拖放支持,以便能够将树内的节点从一个父节点移动到另一个父节点,拖放副本等,但是我找不到任何完整的教程如何实现此目的。我发现了QTreeWidget的一些教程和提示,但不适用于QTreeView和自定义模型。 有人可以指点我在哪里看?

谢谢。

您可以通过将QtGui.QAbstractItemView.InternalMove设置为树视图控件的dragDropMode属性来启用对树视图项目的拖放支持。另外看看这里的文档Using drag & drop with item views。下面是一个树状视图的小例子,其内部拖放功能已启用。

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:树状+抽象与阻力模型和支持拖放

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() 

希望这会有所帮助,至于

+0

谢谢您的回答。 – 2010-11-13 10:04:15

+0

谢谢你的回答。但它不能解决我的问题。我知道使用QStandardItemModel + QStandardItem按预期工作。但我需要使用CUSTOM模型,QAbstractItemModel中的纯子类来工作。我想我需要在模型中实现一些方法,或者为树项目使用一些专用对象。现在拖动甚至不会显示即使放置指示器,即使这被设置为显示...显然,我只是缺少一些东西。 – 2010-11-13 10:09:58

+0

我还有一条评论。如果您在PyQt标准示例中以“simpletreemodel”为例:如何向其添加拖放支持?如果我只是添加setAcceptsDrop(True),setDragEnabled(True),setDragDropMode(view.InternalMove)来查看和标记ItemIsDragEnabled | ItemIsDropEnabled来建模,仅仅具有拖放功能是不够的。 – 2010-11-13 12:10:28