如何在 QTableView 中应用过滤器后显示特定行
How to show specific row after apply filter in QTableView
如何在 QTableView 中应用过滤器后显示隐藏行。我附上了下面的代码,并为过滤值“2”的第二列应用了过滤器。它正在按要求工作。如果要在第二列中显示包含值“3”的隐藏行。它没有显示该行。我使用匹配命令来查找行。一切正常。但行没有显示。请帮我解决这个问题。
from PyQt5.QtWidgets import *
from PyQt5.QtGui import *
from PyQt5.QtCore import *
class TableModel(QAbstractTableModel):
def __init__(self, data):super().__init__();self._data = data
def data(self, index, role):
if role == Qt.ItemDataRole.DisplayRole or role == Qt.EditRole :return self._data[index.row()][index.column()]
def rowCount(self, index):return len(self._data)
def columnCount(self, index):return len(self._data[0])
class tableview(QTableView):
def __init__(self):
super().__init__()
self.setSelectionMode(QAbstractItemView.SelectionMode.NoSelection)
self.setFocusPolicy(Qt.FocusPolicy.NoFocus)
self.horizontalHeader().setStyleSheet("::section{Background-color:lightgray;border-radius:10px;}")
self.smodel = QSortFilterProxyModel()
self.smodel.setFilterKeyColumn(1)
self.setModel(self.smodel)
self.horizontalHeader().setSectionResizeMode(QHeaderView.ResizeMode.ResizeToContents)
self.smodel.setSourceModel(TableModel([[1,2],[1,2],[1,3],[1,4]]))
self.smodel.setFilterFixedString('2')
def find(self,key):
start = self.smodel.index(0, 1)
matches = self.smodel.sourceModel().match(start,Qt.DisplayRole,key,hits=-1,flags=Qt.MatchExactly)
for match in matches:self.showRow(match.row())
app = QApplication([])
table=tableview()
table.show()
b=QPushButton();b.clicked.connect(lambda:table.find('3'))
b.show()
app.exec_()
当前结果
按下按钮所需的结果
我认为 filter
和 showRow()
/hideRow()
可以以不同的方式工作 - 所以他们一起工作可能会有问题。
Filter
在发送到 TableView
之前删除数据,showRow()
/hideRow()
直接删除 TableView
中的行。如果您想使用 showRow
,那么您可能需要清除 filter
、隐藏所有行并显示带有 2
和 3
的行
但是使用过滤器可能更简单
仅显示具有选定值的行 (key = "3"
)
smodel.setFilterFixedString(key)
清除过滤器并显示所有行
smodel.setFilterFixedString("")
要过滤少数值,您可以使用 regex
self.smodel.setFilterRegExp("2|3")
或者您可以将值保留在列表中
filtered = ["2", "3"]
self.smodel.setFilterRegExp( "|".join(filtered) )
最少的工作代码。
我的按钮切换行 "3"
- 第一次点击显示行,第二次点击隐藏行,依此类推
from PyQt5.QtWidgets import *
from PyQt5.QtGui import *
from PyQt5.QtCore import *
class TableModel(QAbstractTableModel):
def __init__(self, data):
super().__init__()
self._data = data
def data(self, index, role):
if role == Qt.ItemDataRole.DisplayRole or role == Qt.EditRole :
return self._data[index.row()][index.column()]
def rowCount(self, index):
return len(self._data)
def columnCount(self, index):
return len(self._data[0])
class tableview(QTableView):
def __init__(self):
super().__init__()
self.setSelectionMode(QAbstractItemView.SelectionMode.NoSelection)
self.setFocusPolicy(Qt.FocusPolicy.NoFocus)
self.horizontalHeader().setStyleSheet("::section{Background-color:lightgray;border-radius:10px;}")
self.horizontalHeader().setSectionResizeMode(QHeaderView.ResizeMode.ResizeToContents)
self.smodel = QSortFilterProxyModel()
self.setModel(self.smodel)
self.smodel.setSourceModel(TableModel([[1,2],[1,2],[1,3],[1,4]]))
self.smodel.setFilterKeyColumn(1)
self.filtered = ["2"]
#self.smodel.setFilterFixedString("2")
self.smodel.setFilterRegExp( "|".join(self.filtered) )
def find(self, key):
print('find:', key)
if key in self.filtered:
self.filtered.remove(key)
else:
self.filtered.append(key)
#self.smodel.setFilterFixedString("") # clear filter - show all rows
#self.smodel.setFilterFixedString(key)
#self.smodel.setFilterRegExp("2|3")
self.smodel.setFilterRegExp( "|".join(self.filtered) )
# --- main ---
app = QApplication([])
table = tableview()
table.show()
button = QPushButton(text="Toggle: 3")
button.clicked.connect(lambda:table.find('3'))
button.show()
app.exec()
顺便说一句:
我只看到一个问题:有些字符在 regex
中有特殊含义,所以添加 ie。点 .
到 filtered
可能会隐藏所有行,因此可能需要使用 \.
.
| ( ) [ ] ^ $
等也会出现同样的问题
如何在 QTableView 中应用过滤器后显示隐藏行。我附上了下面的代码,并为过滤值“2”的第二列应用了过滤器。它正在按要求工作。如果要在第二列中显示包含值“3”的隐藏行。它没有显示该行。我使用匹配命令来查找行。一切正常。但行没有显示。请帮我解决这个问题。
from PyQt5.QtWidgets import *
from PyQt5.QtGui import *
from PyQt5.QtCore import *
class TableModel(QAbstractTableModel):
def __init__(self, data):super().__init__();self._data = data
def data(self, index, role):
if role == Qt.ItemDataRole.DisplayRole or role == Qt.EditRole :return self._data[index.row()][index.column()]
def rowCount(self, index):return len(self._data)
def columnCount(self, index):return len(self._data[0])
class tableview(QTableView):
def __init__(self):
super().__init__()
self.setSelectionMode(QAbstractItemView.SelectionMode.NoSelection)
self.setFocusPolicy(Qt.FocusPolicy.NoFocus)
self.horizontalHeader().setStyleSheet("::section{Background-color:lightgray;border-radius:10px;}")
self.smodel = QSortFilterProxyModel()
self.smodel.setFilterKeyColumn(1)
self.setModel(self.smodel)
self.horizontalHeader().setSectionResizeMode(QHeaderView.ResizeMode.ResizeToContents)
self.smodel.setSourceModel(TableModel([[1,2],[1,2],[1,3],[1,4]]))
self.smodel.setFilterFixedString('2')
def find(self,key):
start = self.smodel.index(0, 1)
matches = self.smodel.sourceModel().match(start,Qt.DisplayRole,key,hits=-1,flags=Qt.MatchExactly)
for match in matches:self.showRow(match.row())
app = QApplication([])
table=tableview()
table.show()
b=QPushButton();b.clicked.connect(lambda:table.find('3'))
b.show()
app.exec_()
当前结果
按下按钮所需的结果
我认为 filter
和 showRow()
/hideRow()
可以以不同的方式工作 - 所以他们一起工作可能会有问题。
Filter
在发送到 TableView
之前删除数据,showRow()
/hideRow()
直接删除 TableView
中的行。如果您想使用 showRow
,那么您可能需要清除 filter
、隐藏所有行并显示带有 2
和 3
但是使用过滤器可能更简单
仅显示具有选定值的行 (key = "3"
)
smodel.setFilterFixedString(key)
清除过滤器并显示所有行
smodel.setFilterFixedString("")
要过滤少数值,您可以使用 regex
self.smodel.setFilterRegExp("2|3")
或者您可以将值保留在列表中
filtered = ["2", "3"]
self.smodel.setFilterRegExp( "|".join(filtered) )
最少的工作代码。
我的按钮切换行 "3"
- 第一次点击显示行,第二次点击隐藏行,依此类推
from PyQt5.QtWidgets import *
from PyQt5.QtGui import *
from PyQt5.QtCore import *
class TableModel(QAbstractTableModel):
def __init__(self, data):
super().__init__()
self._data = data
def data(self, index, role):
if role == Qt.ItemDataRole.DisplayRole or role == Qt.EditRole :
return self._data[index.row()][index.column()]
def rowCount(self, index):
return len(self._data)
def columnCount(self, index):
return len(self._data[0])
class tableview(QTableView):
def __init__(self):
super().__init__()
self.setSelectionMode(QAbstractItemView.SelectionMode.NoSelection)
self.setFocusPolicy(Qt.FocusPolicy.NoFocus)
self.horizontalHeader().setStyleSheet("::section{Background-color:lightgray;border-radius:10px;}")
self.horizontalHeader().setSectionResizeMode(QHeaderView.ResizeMode.ResizeToContents)
self.smodel = QSortFilterProxyModel()
self.setModel(self.smodel)
self.smodel.setSourceModel(TableModel([[1,2],[1,2],[1,3],[1,4]]))
self.smodel.setFilterKeyColumn(1)
self.filtered = ["2"]
#self.smodel.setFilterFixedString("2")
self.smodel.setFilterRegExp( "|".join(self.filtered) )
def find(self, key):
print('find:', key)
if key in self.filtered:
self.filtered.remove(key)
else:
self.filtered.append(key)
#self.smodel.setFilterFixedString("") # clear filter - show all rows
#self.smodel.setFilterFixedString(key)
#self.smodel.setFilterRegExp("2|3")
self.smodel.setFilterRegExp( "|".join(self.filtered) )
# --- main ---
app = QApplication([])
table = tableview()
table.show()
button = QPushButton(text="Toggle: 3")
button.clicked.connect(lambda:table.find('3'))
button.show()
app.exec()
顺便说一句:
我只看到一个问题:有些字符在 regex
中有特殊含义,所以添加 ie。点 .
到 filtered
可能会隐藏所有行,因此可能需要使用 \.
.
| ( ) [ ] ^ $
等也会出现同样的问题