保留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。
当我拖放时,如何保持项目的原始类别?
如this answer中所述,您可以使用setItemPrototype为模型提供项目工厂。但是,如答案中所述,在拖放操作期间只传输某些类型的信息。对于QStandardItem
,这意味着只有item flags和item 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)
我试过这个代码,我得到一个错误。 AttributeError:类型对象的'QStandardItem'没有属性'UserData'然后我用UserType替换UserData,这对一些情况有效,但我仍然困惑...如果我要在__init__ self.userCustomStuff = something中设置,然后我想把它拿到最近扔掉的物品上...我使用type/setType吗?或者我需要数据/ setData?你知道有没有用pyqt/pyside的方式解释它? – Dariusz
@Dariusz。我修正了代码示例。正如我在我的回答中解释的那样,只有项目标志和项目数据通过拖放进行传输。其他任何事情都完全被忽略。所以你必须使用'setData'来为自定义用户数据定制一个自定义角色(这正是我的例子中'type'的作用方式)。如果你想要python风格的属性,你可以通过[@property](http://docs.python.org/3/library/functions.html#property)来实现。 – ekhumoro
只是想让你知道,只有现在(当我开始做C + + Qt)几乎一年后,我现在实际上明白你的意思是什么,我喜欢它大声笑。谢谢! – Dariusz
@ekhumoro感谢您的解决方案!解决方案在你的链接工作,但只有当我有1个自定义类。我如何使用2个自定义类? SubclassQStandardItemA&SubclassQStandardItemB – Dariusz
在这种情况下,您需要采取不同的方法 - 请参阅我的答案以获得一种可能性。 – ekhumoro