猿问

如何使用 QSqlTableModel 为 Qtableview 创建过滤器行?

是否可以使用 QSqlTableModel 为 Qtableview 创建行过滤器。我正在唱“QSqlTableModel”来显示来自正在工作的 SQLite 的 Qtableview 上的数据。但我正在尝试过滤行。当我执行代码时,我遇到的错误是

第 44 行,在 for row in range(self.model.rowCount()) AttributeError: 'QSqlTableModel' object has no attribute 'item'

我试过但没有得到任何解决方案。可以用 QSqlTableModel 来实现吗?当我点击 Qtableview 的任何列时,我想显示来自 tableview 的过滤项目。我将 Qtableview 与 QSqlTableModel 一起使用。

我想做的就像图片中显示的那样

from PyQt5 import QtCore, QtGui, QtWidgets, QtSql

from PyQt5.QtSql import *



class myWindow(QtWidgets.QMainWindow):

    def __init__(self, parent=None):

        super(myWindow, self).__init__(parent)

        self.centralwidget  = QtWidgets.QWidget(self)

        self.view           = QtWidgets.QTableView(self.centralwidget)


        self.gridLayout = QtWidgets.QGridLayout(self.centralwidget)


        self.gridLayout.addWidget(self.view, 1, 0, 1, 3)


        self.setCentralWidget(self.centralwidget)


       # self.model = QtGui.QStandardItemModel(self)


        db = QSqlDatabase.addDatabase("QSQLITE")

        db.setDatabaseName("model.db")

        db.open()


        self.model = QSqlTableModel(self)

        self.model.setTable("sheet")

        self.model.select()

        self.view.setModel(self.model)


        self.proxy = QtCore.QSortFilterProxyModel(self)

        self.proxy.setSourceModel(self.model)


        self.view.setModel(self.proxy)



        self.horizontalHeader = self.view.horizontalHeader()

        self.horizontalHeader.sectionClicked.connect(self.on_view_horizontalHeader_sectionClicked)


12345678_0001
浏览 249回答 1
1回答

慕后森

QSortFilterProxyModel 的实现是为了比较字符串,但在您的情况下,您有不同类型的值,因此必须实现自定义过滤器。为了处理与每个选项关联的不同类型的数据,然后在 QAction 中分别使用 setData() 和 data() 存储和访问值。另一方面,我认为没有必要使用 QSignalMapper 或信号,因为如果 exec_() 方法被选中则返回 QAction,否则返回 None。要访问每个项目的值,必须使用模型的 data() 方法:from PyQt5 import QtCore, QtGui, QtWidgets, QtSqlclass FilterProxyModel(QtCore.QSortFilterProxyModel):    def __init__(self, parent=None):        super().__init__(parent)        self._filter_value = None    @property    def filter_value(self):        return self._filter_value    @filter_value.setter    def filter_value(self, value):        self._filter_value = value        self.invalidateFilter()    def filterAcceptsRow(self, sourceRow, sourceParent):        if self.filter_value is None:            return True        value = (            self.sourceModel()            .index(sourceRow, self.filterKeyColumn(), sourceParent)            .data(self.filterRole())        )        return value == self.filter_valueclass myWindow(QtWidgets.QMainWindow):    def __init__(self, parent=None):        super(myWindow, self).__init__(parent)        self.centralwidget = QtWidgets.QWidget(self)        self.view = QtWidgets.QTableView(self.centralwidget)        self.gridLayout = QtWidgets.QGridLayout(self.centralwidget)        self.gridLayout.addWidget(self.view, 1, 0, 1, 3)        self.setCentralWidget(self.centralwidget)        db = QtSql.QSqlDatabase.addDatabase("QSQLITE")        db.setDatabaseName("model.db")        db.open()        self.model = QtSql.QSqlTableModel(self)        self.model.setTable("sheet")        self.model.select()        self.view.setModel(self.model)        self.proxy = FilterProxyModel(self)        self.proxy.setSourceModel(self.model)        self.view.setModel(self.proxy)        self.horizontalHeader = self.view.horizontalHeader()        self.horizontalHeader.sectionClicked.connect(            self.on_view_horizontalHeader_sectionClicked        )    @QtCore.pyqtSlot(int)    def on_view_horizontalHeader_sectionClicked(self, logicalIndex):        menu = QtWidgets.QMenu(self)        values = []        for row in range(self.model.rowCount()):            value = self.model.index(row, logicalIndex).data(self.proxy.filterRole())            values.append(value)        action_all = QtWidgets.QAction("All", self)        action_all.setData(None)        menu.addAction(action_all)        menu.addSeparator()        for value in sorted(list(set(values))):            action = QtWidgets.QAction(str(value), self)            action.setData(value)            menu.addAction(action)        headerPos = self.view.mapToGlobal(self.horizontalHeader.pos())        posY = headerPos.y() + self.horizontalHeader.height()        posX = headerPos.x() + self.horizontalHeader.sectionPosition(logicalIndex)        action = menu.exec_(QtCore.QPoint(posX, posY))        if action is not None:            self.proxy.setFilterKeyColumn(logicalIndex)            self.proxy.filter_value = action.data()if __name__ == "__main__":    import sys    app = QtWidgets.QApplication(sys.argv)    main = myWindow()    main.show()    main.resize(400, 600)    sys.exit(app.exec_())
随时随地看视频慕课网APP

相关分类

Python
我要回答