Найти - Пользователи
Полная версия: Фильтрация строк в QTableView
Начало » GUI » Фильтрация строк в QTableView
1
g-kit
Доброго дня,

имеется три таблицы QTableView. Каждая последующая таблица имеет ноль и более строк связаных только с одной строкой предыдщей таблицы (master-detail relation). Необходима фильтрация строк во второй и третей таблице только связаных с соответствующей строкой первой таблицы. По видимому по колонке ID, которые во второй и третей таблице будут скрытыми.

В MainForm я делаю вызов функции TABLE2Filter когда строка из первой таблицы выбрана:

 self.connect(self.ui.TABLE1.selectionModel(), QtCore.SIGNAL("currentRowChanged(QModelIndex, QModelIndex)"), self.TABLE2Filter)
Что должна делать TABLE2Filter хорошо описано в книжке Марка Самерфилда на примере с SQL Database

 def assetChanged(self, index):
if index.isValid():
record = self.assetModel.record(index.row())
id = record.value("id").toInt()[0]
self.logModel.setFilter(QString("assetid = %1").arg(id))
else:
self.logModel.setFilter("assetid = -1")
self.logModel.select()
В моем же случае (без SQL - только QTableView) похоже необходимо подключить QSortFilterProxyModel()

            filterTABLE2 = QtGui.QSortFilterProxyModel()
filterTABLE2.setSourceModel(self.TABLE2Model)
self.ui.TABLE2.setModel(filterTABLE2)
но лаконичного метода setFilter() похоже QSortFilterProxyModel() не имеет. Не могу понять каким методом этого класса его можно заменить или организовать логику иначе?

спасибо,
-вадим
hellslade
У QSortFilterProxyModel есть метод filterAcceptsRow(self,sourceRow,sourceParent)
Может это вам нужно?
g-kit
возможно… никак не могу найти и/или понять как как этим методом пользоваться… и чем он (метод) занимается в этой жизни… :-|
hellslade
Чем этот метод занимается в жизни, должно быть понятно из названия :)
Я им пользуюсь так:
Устанавливаю регулярку, по которой следует фильтровать
def textFilterChanged(self):
""" Фильтрация.
"""
caseSensitivity = QtCore.Qt.CaseSensitive if self.filterState.isChecked() else QtCore.Qt.CaseInsensitive
regExp = QtCore.QRegExp(self.filterText.text(), caseSensitivity)
self.mealproxyModel.setFilterRegExp(regExp)
дальше собственно фильтрация:
    def filterAcceptsRow(self, source_row, source_parent):
index1 = self.sourceModel().index(source_row, 1, source_parent)
index2 = self.sourceModel().index(source_row, 2, source_parent)
index3 = self.sourceModel().index(source_row, 3, source_parent)
return (
self.sourceModel().data(index1, QtCore.Qt.DisplayRole).toString().contains(self.filterRegExp()) or
self.sourceModel().data(index2, QtCore.Qt.DisplayRole).toString().contains(self.filterRegExp()) or
self.sourceModel().data(index3, QtCore.Qt.DisplayRole).toString().contains(self.filterRegExp())
)
Кроме setFilterRegExp есть еще пара методов, которыми вам, по видимому, и придется воспользоваться. self.TABLE2Filter примерно такой же как и у меня textFilterChanged, только фильтр устанавливать
g-kit
По видимому по колонке ID
g-kit
спасибо, конечно. А можете еще продемонстрировать self.filterText.text() ?
hellslade
g-kit
так это обычный QLineEdit
g-kit
у меня что-то получилось, но несколько проще. Напомню что необходим фильтр на вторую таблицу, что бы высвечивались только данные связанные с строкой первой таблицы на которой находится курсор в данный момент.

Итак, в MainForm (наименования функций и переменных изменено (по отношению к выше приведенному примеру))
self.connect(self.ui.srcTable.selectionModel(), QtCore.SIGNAL("currentRowChanged(QModelIndex, QModelIndex)"), self.frmTableFilter)
далее работа в функции:

  def frmTableFilter(self):
index = self.ui.srcTable.currentIndex()
if index.isValid():
row = index.row()
srcCode = self.srcTableModel.data(self.srcTableModel.index(row, SRCCODE)).toString() # Получил ID но в текстовом формате, как того ожидает QRegExp
filterFrmTable = QtGui.QSortFilterProxyModel() # Модель
filterFrmTable.setSourceModel(self.frmTableModel) # Модель
self.ui.frmTable.setModel(filterFrmTable) # Модель
filterFrmTable.setDynamicSortFilter(True) #фильтр должен работать на лету
filterFrmTable.setFilterKeyColumn(0) # фильтр применяем по первой колонке
regExp = QtCore.QRegExp(srcCode, QtCore.Qt.CaseInsensitive) # подставил ID в фильтр
filterFrmTable.setFilterRegExp(regExp) # применил фильтр
вроде работает, но как-то подозрительно просто получилось. Боюсь, что чего-то не учел. Где я ошибся?

далее автоинкремент ID в первой таблице и дублирование во вторую?
hellslade
g-kit
как-то подозрительно просто получилось
простое лучше сложного :)
g-kit
Боюсь, что чего-то не учел
если работает, то хорошо. Не ищите ошибок, только потому что “как-то просто получилось”

А зачем каждый раз при фильтрации делать это:
g-kit
filterFrmTable = QtGui.QSortFilterProxyModel() # Модель
filterFrmTable.setSourceModel(self.frmTableModel) # Модель
self.ui.frmTable.setModel(filterFrmTable) # Модель
filterFrmTable.setDynamicSortFilter(True) #фильтр должен работать на лету
filterFrmTable.setFilterKeyColumn(0) # фильтр применяем по первой колонке
Может лучше их вынести из этой функции?
This is a "lo-fi" version of our main content. To view the full version with more information, formatting and images, please click here.
Powered by DjangoBB