2010-11-12 170 views
11

在PyQt 4中,我想創建一個QTreeView,可以通過拖放操作來重新組織它的結構。QTreeView在PyQt中的拖放支持

我已經實現了我自己的QTreeView模型(QAbstractItemModel),所以我的QTreeView正確顯示數據。 現在我想添加對樹節點的拖放支持,以便能夠將樹內的節點從一個父節點移動到另一個父節點,拖放副本等,但是我找不到任何完整的教程如何實現此目的。我發現了QTreeWidget的一些教程和提示,但不適用於QTreeView和自定義模型。 有人可以指點我在哪裏看?

謝謝。

回答

14

您可以通過將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