2016-11-03 59 views
1

我:保留QStandardItem子類中拖放

self.treeView = QTreeView() 
self.treeView.setObjectName("testView") 
self.treeView.setDragDropMode(QAbstractItemView.InternalMove) 
self.treeView.setSelectionMode(QAbstractItemView.ExtendedSelection) 

itemA = SubclassQStandardItemA(self) 
itemB = SubcalssQStandardItemB(self) 

self.model = QStandardItemModel() 
self.treeView.setModel(self.model) 

self.model.appendRow(itemA) 
self.model.appendRow(itemB) 

當我移動到itemB意達,並檢查其類,ItemB不再是SubclassQStandardItemB但QStandardItem。

當我拖放時,如何保持項目的原始類別?

+0

@ekhumoro感謝您的解決方案!解決方案在你的鏈接工作,但只有當我有1個自定義類。我如何使用2個自定義類? SubclassQStandardItemA&SubclassQStandardItemB – Dariusz

+0

在這種情況下,您需要採取不同的方法 - 請參閱我的答案以獲得一種可能性。 – ekhumoro

回答

1

this answer中所述,您可以使用setItemPrototype爲模型提供項目工廠。但是,如答案中所述,在拖放操作期間只傳輸某些類型的信息。對於QStandardItem,這意味着只有item flagsitem data。如果使用多個子類,則無法保留該項目的特定子類。一個模型只能有一個原型,並且用於Qt內部創建的所有項目。

這意味着如果您需要區分不同的項目類型,則不應使用多個QStandardItem子類。相反,你應該使用一個子類,並重新實現QStandardItem.type它們加以區分:

class MyItem(QtGui.QStandardItem): 
    TypeItemA = QtGui.QStandardItem.UserType 
    TypeItemB = QtGui.QStandardItem.UserType + 1 
    TypeItemC = QtGui.QStandardItem.UserType + 2 

    def clone(self): 
     return MyItem() 

    def type(self): 
     return self.data(QtCore.Qt.UserRole + 1000) 

    def setType(self, value): 
     self.setData(QtCore.Qt.UserRole + 1000, value) 

... 

itemA = MyItem(self) 
itemA.setType(MyItem.TypeItemA) 
itemB = MyItem(self) 
itemB.setType(MyItem.TypeItemB) 
+0

我試過這個代碼,我得到一個錯誤。 AttributeError:類型對象的'QStandardItem'沒有屬性'UserData'然後我用UserType替換UserData,這對一些情況有效,但我仍然困惑...如果我要在__init__ self.userCustomStuff = something中設置,然後我想把它拿到最近扔掉的物品上...我使用type/setType嗎?或者我需要數據/ setData?你知道有沒有用pyqt/pyside的方式解釋它? – Dariusz

+1

@Dariusz。我修正了代碼示例。正如我在我的回答中解釋的那樣,只有項目標誌和項目數據通過拖放進行傳輸。其他任何事情都完全被忽略。所以你必須使用'setData'來爲自定義用戶數據定製一個自定義角色(這正是我的例子中'type'的作用方式)。如果你想要python風格的屬性,你可以通過[@property](http://docs.python.org/3/library/functions.html#property)來實現。 – ekhumoro

+0

只是想讓你知道,只有現在(當我開始做C + + Qt)幾乎一年後,我現在實際上明白你的意思是什麼,我喜歡它大聲笑。謝謝! – Dariusz