且构网

分享程序员开发的那些事...
且构网 - 分享程序员编程开发的那些事

QTableView由模型驱动时如何刷新

更新时间:2023-11-13 13:05:28

为此,您可以使用 QSortFilterProxyModel 类.这样,我们就不会篡改实际源模型的结构或其数据.我们只是将主源映射到这个代理模型,视图使用它来显示过滤/排序的数据.我们可以随意影响代理模型中的数据,而不会有篡改源模型的风险.

For this purpose, you can use the QSortFilterProxyModel class. This way, we don't tamper with the actual source model's structure or it's data. We just map the main source to this proxy model, which the view uses to display filtered/sorted data. We can affect the data in the proxy model as we please, without the risk of tampering the source model.

这是您修改后使用的源代码:

Here is your source code modified to use this:

import sys, os
from PyQt4 import QtCore, QtGui
app=QtGui.QApplication(sys.argv)

class TableModel(QtCore.QAbstractTableModel):
    def __init__(self):
        QtCore.QAbstractTableModel.__init__(self)
        self.items=['One','Two','Three','Four','Five','Six','Seven']

    def rowCount(self, parent=QtCore.QModelIndex()):   
        return len(self.items)
    def columnCount(self, index=QtCore.QModelIndex()):
        return 1

    def data(self, index, role):
        if not index.isValid() or not (0<=index.row()<len(self.items)):
            return QtCore.QVariant()

        item=str(self.items[index.row()])

        if role==QtCore.Qt.DisplayRole:
            return item
        else:
            return QtCore.QVariant()


class MySortFilterProxyModel(QtGui.QSortFilterProxyModel):
    def __init__(self):
        super(MySortFilterProxyModel, self).__init__()
        self.cb_status=True

    def cbChanged(self, arg=None):
        self.cb_status=arg
        print self.cb_status
        self.invalidateFilter()

    def filterAcceptsRow(self, sourceRow, sourceParent):
        print_when_odd_flag = self.cb_status
        is_odd = True
        index = self.sourceModel().index(sourceRow, 0, sourceParent)
        print "My Row Data: %s" % self.sourceModel().data(index, role=QtCore.Qt.DisplayRole)

        if (sourceRow + 1) % 2 == 0:
            is_odd = False

        if print_when_odd_flag:
            if is_odd:
                return True
            else:
                return False
        else:
            if not is_odd:
                return True
            else:
                return False


class Window(QtGui.QWidget):
    def __init__(self):
        super(Window, self).__init__()
        mainLayout=QtGui.QHBoxLayout()
        self.setLayout(mainLayout)   

        self.viewA=QtGui.QTableView()
        self.viewA.horizontalHeader().setResizeMode(QtGui.QHeaderView.Stretch) 

        self.myModel=TableModel()

        self.sortModel = MySortFilterProxyModel()
        self.sortModel.setSourceModel(self.myModel)

        self.viewA.setModel(self.sortModel)

        self.checkBox=QtGui.QCheckBox("Show All")  
        self.checkBox.stateChanged.connect(self.sortModel.cbChanged)
        self.checkBox.setChecked(self.sortModel.cb_status)

        mainLayout.addWidget(self.viewA)
        mainLayout.addWidget(self.checkBox)  
        self.show()   

view=Window() 
sys.exit(app.exec_())

如您所见,我已从 UI 和主要源模型中删除了所有连接.主源模型不关心是否设置了复选框.这使它保持解耦.它更干净.代理模型现在被赋予了这个责任.filterAcceptsRow() 根据复选框状态显示的行的索引是奇数还是偶数来执行显示右行的主要繁重工作.

As you can see, I have removed all connection from UI and the main source model. The main source model does not care about whether the checkbox is set or not. This keeps it decoupled. It's cleaner. The proxy model has been given this responsibility now. The filterAcceptsRow() does the main heavy lifting of displaying the right row based on whether the index of the row shown is odd or even based on the checkbox status.

我在其中添加了一些打印语句,以防万一您想根据数据而不是索引更改逻辑.

I have added a few print statements to it, just in case you want to alter the logic based on the data and not the index.

查看关于 QSortFilterProxyModel 和一些示例在这里.

希望这有用.