问题描述
我正在使用pyside2(Qt5)和自定义树视图小部件(MyTreeView
,继承自QTreeView
)来构建GUI。该模型是QStandardItemmodel
对象,而项目是自定义的:MyStandardItem
,继承自QStandardItem
。
问题是:如果在执行拖放操作后检查移动项目的类型,则该项目已变成QStandardItem
,但应该是MyStandardItem
。
我相信问题出在 MimeType 上,经过大量研究,我发现解决方案可能是创建自定义模型并覆盖MIME相关功能。
我试图找出方法,但我做不到。
所以,这是问题:
对于它的价值,这是MyStandardItem
的实现:
class MyStandardItem(QStandardItem):
def __init__(self,text,font,icon_path='',value='',num=0,check_state=None):
super().__init__()
self.setDragEnabled(True)
self.setDropEnabled(True)
self.setText(text)
self.setData({'value': (value,num)})
self.setToolTip(str(self.data()['value']))
self.setFont(font)
self.setIcon(QIcon(icon_path))
self.toggled = check_state
if check_state is not None:
self.setCheckable(True)
self.setCheckState(check_state)
def setCheckState(self,checkState):
super().setCheckState(checkState)
if checkState == Qt.Unchecked:
self.toggled = Qt.Unchecked
else:
self.toggled = Qt.Checked
解决方法
我找到了无需创建自定义模型即可解决此问题的方法。
在MyTreeView.dropEvent
函数中:我没有调用super().dropEvent()
来完成拖放操作,而是由我自己实现的,方法是将项目的数据复制到变量中并创建一个 new MyStandardItem
从这些数据中。然后,我调用insertRow()
将新项目插入给定位置,并调用deleteRow()
删除旧项目。
显然,移动的项目必须在操作(DragEnterEvent()
)开始时存储在class属性中。
一切正常。
PS:我之前已经尝试过这种方法,但是我总是以空行结尾。区别在于,我创建了一个新项目,而不是重新插入旧项目。
这是我的代码的某些部分,以澄清我的意思。请注意,这些函数是MyTreeView的方法。
def dragEnterEvent(self,event: QDragEnterEvent):
if event.source() == self:
self.dragged_item = self.model.itemFromIndex(self.selectionModel().selectedIndexes()[0])
super().dragEnterEvent(event)
else:
...
def dropEvent(self,event: QDropEvent):
index = self.indexAt(event.pos())
if not index.isValid():
return
over_item = self.model.itemFromIndex(index)
over_value = over_item.data()['value'][0]
if event.source() == self:
item_was_moved = self._move_item(over_value,over_parent_value)
if not item_was_moved:
return
else:
...
def _move_item(self,over_value,over_parent_value):
over_value = self._check_indicator_position(over_value)
if over_value is None:
return False
dragged_parent_value = self.dragged_item.parent().data()['value'][0]
dragged_value = self.dragged_item.data()['value'][0]
row = self.dragged_item.row()
items = guifunc.copy_row_items(self.dragged_item,row)
over_value_num = int(over_value.strip('test'))
self.dragged_item.parent().insertRow(over_value_num,items)
if over_value_num < row:
row += 1
self.dragged_item.parent().removeRow(row)
return True