在QAbstractTableModel中删除多行的RemoveRow函数和刷新 – Pyside2

huangapple go评论66阅读模式
英文:

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

huangapple
  • 本文由 发表于 2023年5月11日 01:15:09
  • 转载请务必保留本文链接:https://go.coder-hub.com/76221047.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定