英文:
removing multiple rows in RemoveRow in QAbstractTableModel and refreshing - Pyside2
问题
I have translated the code portion for you:
我有一个使用QAbstractTableModel的QTableView,并尝试创建一些删除行功能。我已经编写了删除行的代码如下 -
def removeRows(self, row, count, parent=QtCore.QModelIndex()):
self.beginRemoveRows(parent, row, row + count - 1)
for i in range(count):
del self._data[row]
self.endRemoveRows()
return True
但是,当调用removeRow时,它不会立即刷新表格,只有在我点击表格上的某个地方后才会刷新。我需要在删除后调用layoutChanged.emit()吗?如果我调用layoutChanged,是否需要调用layoutAboutToBeChanged?
此外,我希望能够删除不在范围内的行。例如,如果用户随机选择了行(例如第1行和第7行),我希望能够删除它们。显然,这个设计只是删除范围内的行,所以不确定是否可以在随机位置删除它们。
**编辑:**
所以我认为我已经能够设置它以删除给定行的随机行,它似乎正在工作。
def removeRows(self, row_indexes, parent=QtCore.QModelIndex()):
self.layoutAboutToBeChanged.emit()
row_indexes.sort(reverse=True)
for row in row_indexes:
self.beginRemoveRows(parent, row, row)
del self._data[row]
self.endRemoveRows()
self.layoutChanged.emit()
return True
要调用它,我这样做
row_index = set()
selected_rows = self.output.selectedIndexes()
for row in selected_rows:
row_index.add(row.row())
self.model.removeRows(list(row_index), self.output_list.currentIndex())
我在执行删除操作之前和之后添加了layoutToBeChanged.emit()和layoutchanged.emit(),现在它正在刷新表格。不确定是否这是正确的方法,在没有layoutchange的情况下,它不会自动刷新。
Please note that I've left the code mostly as-is, but I've made some adjustments to handle the translation.
英文:
I have a QTableView using a QAbstractTableModel and I am trying create some remove row functionality. I have written in the removeRow code like so -
def removeRows(self, row, count, parent=QtCore.QModelIndex()):
self.beginRemoveRows(parent, row, row + count - 1)
for i in range(count):
del self._data[row]
self.endRemoveRows()
return True
When calling a removeRow however it doesn't immediately refresh the table, it will only refresh after I click somewhere on the table. Do I need to call a layoutChanged.emit() after the removal is ran? and would I need to call a layoutAboutToBeChanged if I am calling a layoutChanged?
Also I wanted to be able to remove rows that are not in span. Like if the user cntrl selected random rows (like maybe row 1 and row 7 for example). Clearly this was designed to be setup to only delete rows in a span so not sure if its possible to delete them in random locations.
Edit:
So i think I was able to set it up to remove random rows when give an list of rows, it seems to be working.
def removeRows(self, row_indexes, parent=QtCore.QModelIndex()):
self.layoutAboutToBeChanged.emit()
row_indexes.sort(reverse=True)
for row in row_indexes:
self.beginRemoveRows(parent, row, row)
del self._data[row]
self.endRemoveRows()
self.layoutChanged.emit()
return True
And to call it I do this
row_index = set()
selected_rows = self.output.selectedIndexes()
for row in selected_rows:
row_index.add(row.row())
self.model.removeRows(list(row_index), self.output_list.currentIndex())
I added the layoutToBeChanged.emit() and layoutchanged.emit() before and after doing the removal, and it is now refreshing the table. Not sure if that is the right way to do it, without the layoutchange it doesn't refresh it automatically.
This is my entire QabstractTableModel class
class FileTableModel(QtCore.QAbstractTableModel):
def __init__(self, data):
super(FileTableModel, self).__init__()
self._data = data
self.headers = ['File Name', 'Path', 'File Size', 'Modified Date', 'Creation Date']
def data(self, index, role):
if role == QtCore.Qt.DisplayRole:
value = self._data[index.row()][index.column()]
if isinstance(value, datetime):
return datetime.strftime(value, "%m/%d/%Y %X %p")
elif isinstance(value, int):
return size_conversion(value)
else:
return value
def rowCount(self, index):
return len(self._data)
def columnCount(self, index):
return len(self._data[0])
def headerData(self, section, orientation, role=QtCore.Qt.DisplayRole):
if orientation == QtCore.Qt.Horizontal and role == QtCore.Qt.DisplayRole:
return self.headers[section]
def sort(self, column, order=QtCore.Qt.AscendingOrder):
self.layoutAboutToBeChanged.emit()
self._data.sort(key=lambda x: x[column], reverse=order == QtCore.Qt.DescendingOrder)
self.layoutChanged.emit()
def removeRows(self, row_indexes, parent=QtCore.QModelIndex()):
self.layoutAboutToBeChanged.emit()
row_indexes.sort(reverse=True)
for row in row_indexes:
self.beginRemoveRows(parent, row, row)
del self._data[row]
self.endRemoveRows()
self.layoutChanged.emit()
return True
答案1
得分: 1
以下是翻译好的部分:
这是我自己的多行删除实现。行列表被分成连续的切片,以便尽可能高效地进行删除操作。
@staticmethod
def continuous_slices(numbers):
if not numbers:
return
numbers.sort(reverse=True)
start_idx = 0
for idx in range(1, len(numbers)):
if numbers[idx - 1] > (numbers[idx] + 1):
yield numbers[idx - 1], numbers[start_idx]
start_idx = idx
yield numbers[-1], numbers[start_idx]
def removeRows(self, row_indices, parent=QtCore.QModelIndex()):
for first, last in self.continuous_slices(row_indices):
self.beginRemoveRows(parent, first, last)
del self._data[first: last + 1]
self.endRemoveRows()
return True
英文:
Here's my own implementation for removing multiple rows. The list of rows is chopped up into continuous slices so the removal can be done as efficiently as possible.
@staticmethod
def continuous_slices(numbers):
if not numbers:
return
numbers.sort(reverse=True)
start_idx = 0
for idx in range(1, len(numbers)):
if numbers[idx - 1] > (numbers[idx] + 1):
yield numbers[idx - 1], numbers[start_idx]
start_idx = idx
yield numbers[-1], numbers[start_idx]
def removeRows(self, row_indices, parent=QtCore.QModelIndex()):
for first, last in self.continuous_slices(row_indices):
self.beginRemoveRows(parent, first, last)
del self._data[first: last + 1]
self.endRemoveRows()
return True
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论