Как искать данные QSqlTableModel, Qtableview из QlineEdit с помощью QcomboBox? - PullRequest
0 голосов
/ 07 августа 2020

Я использую 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.

Я добавил элементы «Все», «Имя», «Возраст» и «Адрес» в поле со списком, и я пытаюсь искать или фильтровать данные из QlineEdit с использованием QcomboBox, как если бы я выбирал «Все» в cobobox и когда я набираю слова в QlineEdit, которые должны фильтровать данные из всех столбцов.

Если я выберу «Имя» или « Возраст »или« Адрес »в QcomboBox, который должен содержать данные фильтрации в соответствии с выбором имени столбца в Qcombobox. В моей базе данных есть String и Int Values. Есть ли для этого примеры?

введите описание изображения здесь

1 Ответ

1 голос
/ 07 августа 2020

Необходимо правильно использовать 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)
...