QStandardItem子类中clone的实现
Implementation of clone in QStandardItem subclass
我正在使用带有 QTreeView 的 QStandardItemModel 来显示自定义项。这些项目分为三种不同类型 FILTER_TYPE、MODIFIER_TYPE 和 GROUP_TYPE。
我希望能够在视图中使用拖放操作 (InternalMove) 对模型中的项目重新排序。如果我理解正确,我必须在我的模型上使用 setItemPrototype(MyItem()) 以便它在移动项目时使用自定义 MyItem 而不是一般的 QStandardItem。
我的理解是创建自定义 MyItem 的新实例,然后将旧项目的所有数据和标志复制到新项目。但是,该模型似乎只初始化了一个新的 MyItem 而从不复制数据。
因此:如何在 MyItem subclass 中重新实现 QStandardItem.clone() 以将所有数据和标志复制到新项目中?我是否必须手动检查所有自定义数据角色并将它们的值分配给新项目?
项目 class 看起来像这样:
class MyItem(QtGui.QStandardItem):
FILTER_TYPE = QtGui.QStandardItem.UserType + 1
MODIFIER_TYPE = QtGui.QStandardItem.UserType + 2
GROUP_TYPE = QtGui.QStandardItem.UserType + 3
TYPE = QtCore.Qt.UserRole + 0
NAME = QtCore.Qt.UserRole + 1
IS_PROCESSED = QtCore.Qt.UserRole + 5
OUTPUT = QtCore.Qt.UserRole + 6
FN = QtCore.Qt.UserRole + 7
DEFAULT_PARAMS = QtCore.Qt.UserRole + 8
PARAMETER_SET = QtCore.Qt.UserRole + 9
def __init__(self):
super().__init__()
self.name = ""
self.full_name = ""
self.description = ""
self.fn = None
self.default_params = None
self.parameter_set = None
self.is_active = True
self.is_processed = False
self.output = None
self.icon = QtGui.QIcon()
def clone(self):
item = Item()
??? WHAT GOES HERE TO COPY ALL DATA AND FLAGS ???
return item
def __setattr__(self, name, value):
if name == 'name':
self.setData(value, self.NAME)
elif name == 'full_name':
self.setData(value, QtCore.Qt.DisplayRole)
self.setData(value, QtCore.Qt.EditRole)
elif name == 'description':
self.setData(value, QtCore.Qt.ToolTipRole)
...
else:
super().__setattr__(name, value)
def __getattribute__(self, name):
if name == 'name':
return self.data(self.NAME)
elif name == 'full_name':
return self.data(QtCore.Qt.DisplayRole)
elif name == 'description':
return self.data(QtCore.Qt.ToolTipRole)
...
else:
return super().__getattribute__(name)
def initializeItem(self, type_, name, full_name, description="", fn=None, default_params=None):
self.name = name
self.full_name = full_name
self.description = description
self.fn = fn
self.default_params = default_params
self.parameter_set = ParameterSet(params_list=default_params)
self.setData(type_, self.TYPE)
flags = QtCore.Qt.ItemIsSelectable|QtCore.Qt.ItemIsDragEnabled|QtCore.Qt.ItemIsUserCheckable|QtCore.Qt.ItemIsEnabled
if type_ == self.FILTER_TYPE:
self.icon = QtGui.QIcon('resources/filter.png')
flags = flags|QtCore.Qt.ItemNeverHasChildren
elif type_ == self.MODIFIER_TYPE:
self.icon = QtGui.QIcon('resources/modifier.png')
flags = flags|QtCore.Qt.ItemIsDropEnabled
elif type_ == self.GROUP_TYPE:
self.icon = QtGui.QIcon('resources/folder.png')
flags = flags|QtCore.Qt.ItemIsDropEnabled|QtCore.Qt.ItemIsEditable
self.setFlags(flags)
def type(self):
return self.data(self.TYPE)
模型实现如下所示:
from tree.items import MyItem
class TreeModel(QtGui.QStandardItemModel):
def __init__(self):
super().__init__()
self.setItemPrototype(MyItem())
“克隆”的逻辑是创建一个具有与项目相同信息的对象,因此在这种情况下,您使用角色来存储该信息,因此您必须将所有信息复制到新项目中,在这种情况下你可以使用 QDataStream:
def clone(self):
item = MyItem()
ba = QtCore.QByteArray()
ds = QtCore.QDataStream(ba, QtCore.QIODevice.WriteOnly)
ds << self
ds = QtCore.QDataStream(ba)
ds >> item
return item
我正在使用带有 QTreeView 的 QStandardItemModel 来显示自定义项。这些项目分为三种不同类型 FILTER_TYPE、MODIFIER_TYPE 和 GROUP_TYPE。
我希望能够在视图中使用拖放操作 (InternalMove) 对模型中的项目重新排序。如果我理解正确,我必须在我的模型上使用 setItemPrototype(MyItem()) 以便它在移动项目时使用自定义 MyItem 而不是一般的 QStandardItem。
我的理解是创建自定义 MyItem 的新实例,然后将旧项目的所有数据和标志复制到新项目。但是,该模型似乎只初始化了一个新的 MyItem 而从不复制数据。
因此:如何在 MyItem subclass 中重新实现 QStandardItem.clone() 以将所有数据和标志复制到新项目中?我是否必须手动检查所有自定义数据角色并将它们的值分配给新项目?
项目 class 看起来像这样:
class MyItem(QtGui.QStandardItem):
FILTER_TYPE = QtGui.QStandardItem.UserType + 1
MODIFIER_TYPE = QtGui.QStandardItem.UserType + 2
GROUP_TYPE = QtGui.QStandardItem.UserType + 3
TYPE = QtCore.Qt.UserRole + 0
NAME = QtCore.Qt.UserRole + 1
IS_PROCESSED = QtCore.Qt.UserRole + 5
OUTPUT = QtCore.Qt.UserRole + 6
FN = QtCore.Qt.UserRole + 7
DEFAULT_PARAMS = QtCore.Qt.UserRole + 8
PARAMETER_SET = QtCore.Qt.UserRole + 9
def __init__(self):
super().__init__()
self.name = ""
self.full_name = ""
self.description = ""
self.fn = None
self.default_params = None
self.parameter_set = None
self.is_active = True
self.is_processed = False
self.output = None
self.icon = QtGui.QIcon()
def clone(self):
item = Item()
??? WHAT GOES HERE TO COPY ALL DATA AND FLAGS ???
return item
def __setattr__(self, name, value):
if name == 'name':
self.setData(value, self.NAME)
elif name == 'full_name':
self.setData(value, QtCore.Qt.DisplayRole)
self.setData(value, QtCore.Qt.EditRole)
elif name == 'description':
self.setData(value, QtCore.Qt.ToolTipRole)
...
else:
super().__setattr__(name, value)
def __getattribute__(self, name):
if name == 'name':
return self.data(self.NAME)
elif name == 'full_name':
return self.data(QtCore.Qt.DisplayRole)
elif name == 'description':
return self.data(QtCore.Qt.ToolTipRole)
...
else:
return super().__getattribute__(name)
def initializeItem(self, type_, name, full_name, description="", fn=None, default_params=None):
self.name = name
self.full_name = full_name
self.description = description
self.fn = fn
self.default_params = default_params
self.parameter_set = ParameterSet(params_list=default_params)
self.setData(type_, self.TYPE)
flags = QtCore.Qt.ItemIsSelectable|QtCore.Qt.ItemIsDragEnabled|QtCore.Qt.ItemIsUserCheckable|QtCore.Qt.ItemIsEnabled
if type_ == self.FILTER_TYPE:
self.icon = QtGui.QIcon('resources/filter.png')
flags = flags|QtCore.Qt.ItemNeverHasChildren
elif type_ == self.MODIFIER_TYPE:
self.icon = QtGui.QIcon('resources/modifier.png')
flags = flags|QtCore.Qt.ItemIsDropEnabled
elif type_ == self.GROUP_TYPE:
self.icon = QtGui.QIcon('resources/folder.png')
flags = flags|QtCore.Qt.ItemIsDropEnabled|QtCore.Qt.ItemIsEditable
self.setFlags(flags)
def type(self):
return self.data(self.TYPE)
模型实现如下所示:
from tree.items import MyItem
class TreeModel(QtGui.QStandardItemModel):
def __init__(self):
super().__init__()
self.setItemPrototype(MyItem())
“克隆”的逻辑是创建一个具有与项目相同信息的对象,因此在这种情况下,您使用角色来存储该信息,因此您必须将所有信息复制到新项目中,在这种情况下你可以使用 QDataStream:
def clone(self):
item = MyItem()
ba = QtCore.QByteArray()
ds = QtCore.QDataStream(ba, QtCore.QIODevice.WriteOnly)
ds << self
ds = QtCore.QDataStream(ba)
ds >> item
return item