QTableView() 仅在选择时更新更改

Posted

技术标签:

【中文标题】QTableView() 仅在选择时更新更改【英文标题】:QTableView() only updates changes when selected 【发布时间】:2020-04-18 09:59:03 【问题描述】:

我已将数据插入到子类QAbstractListModel 中并用QListViewQTableView 显示它 更改(删除一行)立即显示在QListView 中,但仅在选择表视图时才会显示在QTableView 中 sublcased 模型包含 setData 方法和 self.dataChanged.emit(index, index) 内部所以它应该更新自己。 为什么`QTableView 没有立即更新自己?

#!/usr/bin/env python

"""
minimum code to run a model view

"""



import sys
from PyQt5 import QtWidgets as qtw
from PyQt5 import QtCore as qtc
from PyQt5 import QtGui as qtg


class ViewModel(qtc.QAbstractListModel):
    def __init__(self, input_data=None):
        super().__init__()
        self.input_data = input_data or []




    # naming of rows ,columns static !!
    def headerData(self, section, orientation, role):
        if role == qtc.Qt.DisplayRole:
            if orientation == qtc.Qt.Horizontal:


                return "dude" # todo dynamic labeling
            else:

                return "leboswki"  # todo dynamic labeling



    def data(self, index, role):

        if role == qtc.Qt.DisplayRole:
            row = index.row() # == wie liste[row] der index

            item = self.input_data[row]
            return item




    def rowCount(self, index): # parameter inside is needed !

        return len(self.input_data)



    def flags(self, index):
        return qtc.Qt.ItemIsEditable | qtc.Qt.ItemIsSelectable | qtc.Qt.ItemIsEnabled



    def setData(self, index, value, role):

        if role == qtc.Qt.EditRole:
            row = index.row()
            if index.isValid():
                self.input_data[row] = value
                self.dataChanged.emit(index, index)
                return True
            else:
                return False


    def removeRows(self, position, rows, parent=qtc.QModelIndex()):
        self.beginRemoveRows(parent, position, position + rows-1)

        for i in range(rows):
            value = self.input_data[position]
            self.input_data.remove(value)

        self.endRemoveRows()
        return True





class MainWindow(qtw.QWidget):
    def __init__(self):
        super().__init__()

        # View
        list_view = qtw.QListView()
        self.model = ViewModel(input_data=["text1", "text2", "text3", "text4"])
        list_view.setModel(self.model)


        table_view = qtw.QTableView()
        table_view.setModel(self.model)


        # widgets
        self.deleate_row_button = qtw.QPushButton("deleate rows")

        # layout
        qvboxlayout = qtw.QVBoxLayout()
        qvboxlayout.addWidget(list_view)
        qvboxlayout.addWidget(table_view)
        qvboxlayout.addWidget(self.deleate_row_button)
        self.setLayout(qvboxlayout)
        self.show()

        # function
        self.deleate_row_button.clicked.connect(lambda: self.model.removeRows(-1, 1))


if __name__ == '__main__':
    app = qtw.QApplication(sys.argv)
    w = MainWindow()
    sys.exit(app.exec_())


【问题讨论】:

【参考方案1】:

虽然在 Python 中您可以访问负索引,但在 Qt 中不会发生导致错误的情况。解决方案是将负索引转换为正索引。另一方面,不要按行的值 (self.input_data.remove(value)) 删除行,因为如果它有 2 行具有相同的文本,则可能会出现错误。

def rowCount(self, index=qtc.QModelIndex()):
    return 0 if index.isValid() else len(self.input_data)
def removeRows(self, position, rows, parent=qtc.QModelIndex()):
    position = (position + self.rowCount()) if position < 0 else position
    start = position
    end = position + rows - 1
    self.beginRemoveRows(parent, start, end)
    del self.input_data[start : end + 1]
    self.endRemoveRows()
    return True

【讨论】:

以上是关于QTableView() 仅在选择时更新更改的主要内容,如果未能解决你的问题,请参考以下文章

选择多行时QTableView变得很慢

选择单元格时,更改 QTableView 中图标的颜色突出显示

合并 - 仅在值更改时更新

是否可以仅在数据发生更改时更新 mysql 视图?

QTableview 从过滤模型中选择项目

PyQt 5 QTableView 选择栏问题