python - QAbstratctTableModel - 删除行

标签 python pyside maya pyside2

代码即将完成。交易如下:

它是Python和PySide。我有一个 QAbstractTableModel 和一个 QTableView。

我无法正确删除行。我认为问题出在我删除其中一个行的索引中......

这是我使用的按钮委托(delegate):

class ButtonDelegate(QItemDelegate):

    def __init__(self, parent):
        QItemDelegate.__init__(self, parent)

    def paint(self, painter, option, index):

        widget = QWidget()
        layout = QHBoxLayout()
        widget.setLayout(layout)
        btn = QPushButton("X")
        btn.clicked.connect(partial(self.parent().cellButtonClicked, index))
        layout.addWidget(btn)
        layout.setContentsMargins(2,2,2,2)

        if not self.parent().indexWidget(index):
            self.parent().setIndexWidget(index, widget)

这是 cellButtonClicked 方法,它位于表格 View 下:

class Table(QTableView):

def __init__(self, *args, **kwargs):
    QTableView.__init__(self, *args, **kwargs)

    self.setItemDelegateForColumn(6, ButtonDelegate(self))
    self.setItemDelegateForColumn(0, EmptyDelegate(self))

    self.setSortingEnabled(True)

def cellButtonClicked(self, index,  *args):

    model = self.model()
    model.removeRow(index.row())

这是模型的removeRow方法:

def removeRow(self, row, parent = QtCore.QModelIndex()):

    self.beginRemoveRows(parent, row, row)

    array = []
    for i in range(7):
        if i == 0:
            array.append(self.index(row, i).data())
        else:
            array.append(str(self.index(row, i).data()))

    self.cycles.remove(array)

    self.endRemoveRows()

    # update custom node in maya. 
    self.getData()

我认为,主要的问题是,当我删除一行时,它不会更新模型的索引。因此,当我再次单击任何删除按钮时,它会以不再与模型的 rowCount 匹配的索引启动 de removeRow() ,因此我无法构建要从模型数据中删除的数组。

这有意义吗?如果您需要更多代码,请告诉我您需要什么。

最佳答案

这个问题是因为你在创建每个委托(delegate)时设置了该行的值,所以它的值没有更新。

一个可能的解决方案是使用 lambda 函数传递与临时 QModelIndex 关联的 QPersistenModelIndex,但我发现存在意外行为,即创建一个选择,所以我调用了 clearSelection()

无需连接到 cellButtonClicked 插槽,因为您可以使用 QModelIndex 或 QPersistenModelIndex 直接访问模型。

class ButtonDelegate(QItemDelegate):
    def __init__(self, parent):
        QItemDelegate.__init__(self, parent)

    def paint(self, painter, option, index):
        widget = QWidget()
        layout = QHBoxLayout()
        widget.setLayout(layout)
        btn = QPushButton("X")
        ix = QPersistentModelIndex(index)
        btn.clicked.connect(lambda ix = ix : self.onClicked(ix))
        layout.addWidget(btn)
        layout.setContentsMargins(2,2,2,2)
        if not self.parent().indexWidget(index):
            self.parent().setIndexWidget(index, widget)

    def onClicked(self, ix):
        model = ix.model()
        model.removeRow(ix.row())
        self.parent().clearSelection()

另一个选项是通过 editorEvent 处理点击事件,因为提供的 QModelIndex 已更新值,如下所示:

class ButtonDelegate(QStyledItemDelegate):
    def __init__(self, parent):
        QStyledItemDelegate.__init__(self, parent)
        self.state = QStyle.State_Enabled

    def paint(self, painter, option, index):
        button = QStyleOptionButton()
        button.rect = self.adjustRect(option.rect)
        button.text = "X"
        button.state = self.state
        QApplication.style().drawControl(QStyle.CE_PushButton, button, painter)

    def editorEvent(self, event, model, option, index):
        if event.type() == QEvent.Type.MouseButtonPress:
            self.state = QStyle.State_On
            return True
        elif event.type() == QEvent.Type.MouseButtonRelease:
            r = self.adjustRect(option.rect)
            if r.contains(event.pos()):
                model.removeRow(index.row())
            self.state = QStyle.State_Enabled
        return True

    @staticmethod
    def adjustRect(rect):
        r = QRect(rect)
        margin = QPoint(2, 2)
        r.translate(margin)
        r.setSize(r.size()-2*QSize(margin.x(), margin.y()))
        return r

除此之外,不需要迭代data(),我们可以直接删除该行:

def removeRow(self, row, parent=QModelIndex()):
    self.beginRemoveRows(parent, row, row)
    self.cycles.remove(self.cycles[row])
    self.endRemoveRows()
    self.getData()

如下link这两个选项均已实现。

关于python - QAbstratctTableModel - 删除行,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/48103030/

相关文章:

python - PySide:向菜单栏添加切换选项/操作

python - PyQt 获取ListWidget中的特定值

python - 如何在我的类中继承QtWidgets.QWidget并使我的类类型-QtWidgets.QWidget?

python - 如何在 Maya python ls 命令中选择顶点?

Python 简单浮点除法 : not accurate

python - 将列表元素作为函数的参数一一传递

qt - 在 QT 中链接对话框的最佳方式是什么?

python - PYQT:如何捕获python解释器的输出并将其显示在QEditText中?

python - Django:删除/删除 slug

python - 如何在 matplotlib 中设置图形(而不是图形!)大小