2016-11-03 108 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