QAbstratctTableModel - removeRows
QAbstratctTableModel - removeRows
代码即将完成。这是交易:
是python和PySide。我有一个 QAbstractTableModel 和一个 QTableView。
我无法正确删除行。我认为问题出在行的索引中,我删除了其中一个...
这是我使用的按钮委托:
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 方法,它在 table 视图下:
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()
我认为,主要的问题是,当我删除一行时,它不会更新模型的索引。因此,当我再次单击任何删除按钮时,它会启动 de removeRow(),其索引不再与模型的 rowCount 匹配,因此我无法构建要从模型数据中删除的数组。
有道理吗?如果您需要更多代码,请告诉我您需要什么。
问题是因为您在创建每个委托时设置了该行的值,所以它的值没有更新。
一个可能的解决方案是使用 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和PySide。我有一个 QAbstractTableModel 和一个 QTableView。
我无法正确删除行。我认为问题出在行的索引中,我删除了其中一个...
这是我使用的按钮委托:
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 方法,它在 table 视图下:
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()
我认为,主要的问题是,当我删除一行时,它不会更新模型的索引。因此,当我再次单击任何删除按钮时,它会启动 de removeRow(),其索引不再与模型的 rowCount 匹配,因此我无法构建要从模型数据中删除的数组。
有道理吗?如果您需要更多代码,请告诉我您需要什么。
问题是因为您在创建每个委托时设置了该行的值,所以它的值没有更新。
一个可能的解决方案是使用 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两个选项都实现了。