Qt拖放对自定义项不起作用

2024-09-30 06:15:07 发布

您现在位置:Python中文网/ 问答频道 /正文

我正在使用PySide2(Qt5)和一个自定义的treeview小部件(MyTreeView,继承自QTreeView)构建一个GUI。模型是一个QStandardItemModel对象,而项是从QStandardItem继承的自定义:MyStandardItem

问题是:如果我在执行拖放操作后检查移动项的类型,它将变成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

Tags: 函数模型selftruevaluedefcheck解决方案
1条回答
网友
1楼 · 发布于 2024-09-30 06:15:07

我找到了一种解决这个问题的方法,而不必创建自定义模型

MyTreeView.dropEvent函数中:我不会调用super().dropEvent()来完成拖动&;删除操作,但我通过在变量中复制项的数据并从这些数据创建一个新的MyStandardItem来实现它。然后我调用insertRow()在给定位置插入新项,调用deleteRow()删除旧项。 显然,移动的项必须存储在操作开始时的class属性中(DragEnterEvent())。 一切都很完美

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

相关问题 更多 >

    热门问题