【问题标题】:How to search data QSqlTableModel, Qtableview from QlineEdit with the help of QcomboBox?如何借助QcomboBox从QlineEdit中搜索数据QSqlTableModel、Qtableview?
【发布时间】:2020-11-27 17:25:01
【问题描述】:

我使用 QSqlTableModel, (FilterProxyModel) 作为自定义代理模型与 QtCore.QSortFilterProxyModel, QTableView,Qcombobox。

self.lineEdit       = QtWidgets.QLineEdit(self.centralwidget)
self.view           = QtWidgets.QTableView(self.centralwidget)
self.comboBox       = QtWidgets.QComboBox(self.centralwidget)

以下代码是自定义过滤器类,用于从 tableview 获取列菜单:

class 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_value

下面是数据库模型:

    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 = FilterProxyModel(self)###
    self.proxy.setSourceModel(self.model)

    self.view.setModel(self.proxy)

以下是我的问题的详细信息

    column_names = (["All","Name", "Age", "Adress"])
    self.comboBox.addItems([x for x in column_names])


@QtCore.pyqtSlot(str)
def msa_lineEdit_textChanged(self, text):
    self.proxy = QtCore.QSortFilterProxyModel(self)
    self.proxy.setSourceModel(self.model)
    self.view.setModel(self.proxy)
    search = QtCore.QRegExp(    text,
                                QtCore.Qt.CaseInsensitive,
                                QtCore.QRegExp.RegExp
                                )

    self.proxy.setFilterRegExp(search)

例如:我尝试使用 QtCore.QRegExp.RegExp 使用上述函数,它在第一列中显示数据,在 Qcombobox 中选择“全部”。

我在组合框中添加了项目“All”、“Name”、“Age”和“Adress”,我正在尝试使用 QcomboBox 从 QlineEdit 中搜索或过滤数据,就好像我在 cobobox 中选择了“All”一样当我在 QlineEdit 中输入应该过滤所有列的数据时。

如果我在 QcomboBox 上选择“姓名”或“年龄”或“地址”,则应根据 Qcombobox 中的列名选择过滤数据。我的数据库有字符串和整数值。有没有可用的例子?

【问题讨论】:

  • 我有一个问题:您使用的代码来自我之前的回答,因为它适用于所有类型的数据,例如“年龄”列是整数,您想如何应用数字的正则表达式?
  • @eyllanesc。我不知道。我试过了。有什么办法吗?
  • 我的问题不是问你能不能,而是反思你的要求。
  • @eyllanesc.Yes 根据你之前的答案整数值也在那里。
  • @eyllanesc. 数据库也一样。还是需要我共享数据库。

标签: python-3.x pyqt5 qtableview qsortfilterproxymodel qsqltablemodel


【解决方案1】:

你必须正确使用filterKeyColumn

此属性保存用于从其中读取用于过滤源模型内容的键的列。

默认值为0。如果值为-1,则从所有列中读取键。

因此您可以将行编辑的textChanged 信号组合的currentIndexChanged 连接到函数,然后相应地设置过滤器:

def msa_lineEdit_textChanged(self):
    search = QtCore.QRegExp(self.lineEdit.text(), 
        QtCore.Qt.CaseInsensitive, QtCore.QRegExp.RegExp)
    self.proxy.setFilterKeyColumn(self.combo.currentIndex() - 1)
    self.proxy.setFilterRegExp(search)

请注意,如果您使用 setFilterRegExp,您的自定义代理将无法按预期工作,这是因为您覆盖了 filterAcceptsRow 方法。

您应该像这样更改实现:

    def filterAcceptsRow(self, sourceRow, sourceParent):
        if self.filter_value is None:
            return super().filterAcceptsRow(sourceRow, sourceParent)
        if self.filterKeyColumn() >= 0:
            value = (
                self.sourceModel()
                .index(sourceRow, self.filterKeyColumn(), sourceParent)
                .data(self.filterRole())
            )
            return value == self.filter_value
        for column in range(self.columnCount()):
            value = (
                self.sourceModel()
                .index(sourceRow, column, sourceParent)
                .data(self.filterRole())
            )
            if value == self.filter_value:
                return True
        return False

您还应该在应用正则表达式过滤器时清除该属性:

    def setFilterRegExp(self, filter):
        self.filter_value = None
        super().setFilterRegExp(filter)

【讨论】:

  • 我添加了您的答案并使用了“self.lineEdit.textChanged.connect(self.msa_lineEdit_textChanged)”。当我在 Qlineedit 上打字时它没有响应。
  • 自定义过滤器“class FilterProxyModel(QtCore.QSortFilterProxyModel):”是否影响“self.proxy.setFilterRegExp(search)”?我不知道。
  • @musicamante。根据您的注意,不应每次都创建新的代理实例。那么如何将原始“QSortFilterProxyModel”调用到“def msa_lineEdit_textChanged(self):”函数中。连同上面使用的自定义 FilterProxyModel。
  • 我不明白你在问什么。而且我不知道为什么它对您不起作用,但是如果您仍在使用 pyqtSlot 装饰器,请将其删除:如您所见,我没有使用它,并且插槽装饰器很少需要信号/slot 连接。
  • 如果您在自定义模型上调用setFilterRegExp 并且未设置filter_value,则结果是根本没有过滤(因为filterAcceptsRow 的实现在中返回True这种情况)。查看更新。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-06-04
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多