使用 QSortFilterProxyModel 对 QTableView 进行排序后保留选择
Keep the selection after using QSortFilterProxyModel to sort a QTableView
我发现了一个类似的问题。
Keep the selection after filtering a QTableView with a QSortFilterProxyModel
但是是关于C++ QT的,我自己试了很多次,还是没在PyQt5或者PySide6中搞定?
import sys
from PyQt5.QtWidgets import QApplication, QWidget, QLineEdit, QTableView, QHeaderView, QVBoxLayout
from PyQt5.QtCore import Qt, QSortFilterProxyModel
from PyQt5.QtGui import QStandardItemModel, QStandardItem
class AppDemo(QWidget):
def __init__(self):
super().__init__()
self.resize(1200, 1000)
mainLayout = QVBoxLayout()
# companies = ('Apple', 'Facebook', 'Google', 'Amazon', 'Walmart', 'Dropbox', 'Starbucks', 'eBay', 'Canon')
companies = [f'company_{i}' for i in range(200)]
model = QStandardItemModel(len(companies), 1)
model.setHorizontalHeaderLabels(['Company'])
for row, company in enumerate(companies):
item = QStandardItem(company)
model.setItem(row, 0, item)
filter_proxy_model = QSortFilterProxyModel()
filter_proxy_model.setSourceModel(model)
filter_proxy_model.setFilterCaseSensitivity(Qt.CaseInsensitive)
filter_proxy_model.setFilterKeyColumn(0)
search_field = QLineEdit()
search_field.textChanged.connect(filter_proxy_model.setFilterRegExp)
mainLayout.addWidget(search_field)
table = QTableView()
table.setStyleSheet('font-size: 35px;')
table.verticalHeader().setSectionResizeMode(QHeaderView.Stretch)
table.horizontalHeader().setSectionResizeMode(QHeaderView.Stretch)
table.setModel(filter_proxy_model)
mainLayout.addWidget(table)
self.setLayout(mainLayout)
app = QApplication(sys.argv)
demo = AppDemo()
demo.show()
sys.exit(app.exec_())
我自己找到了解决办法。我改为使用 QListWidget。但同样的逻辑也可以应用于 QListView。下面是代码。
下面是核心部分,是一个slot,接一个line edit。这样做,效率很好,特别是当你有很多项目时,因为当 lineedit 输入更改时它不使用 QListWidget.clear(),它只是将项目隐藏在幕后。
# deal with search file
def onFileTextChanged(self, text):
search_items = self.listWidget.findItems(text, Qt.MatchContains)
for index in range(self.listWidget.count()):
item = self.listWidget.item(index)
if item in search_items:
item.setHidden(False)
else:
item.setHidden(True)
我发现了一个类似的问题。 Keep the selection after filtering a QTableView with a QSortFilterProxyModel 但是是关于C++ QT的,我自己试了很多次,还是没在PyQt5或者PySide6中搞定?
import sys
from PyQt5.QtWidgets import QApplication, QWidget, QLineEdit, QTableView, QHeaderView, QVBoxLayout
from PyQt5.QtCore import Qt, QSortFilterProxyModel
from PyQt5.QtGui import QStandardItemModel, QStandardItem
class AppDemo(QWidget):
def __init__(self):
super().__init__()
self.resize(1200, 1000)
mainLayout = QVBoxLayout()
# companies = ('Apple', 'Facebook', 'Google', 'Amazon', 'Walmart', 'Dropbox', 'Starbucks', 'eBay', 'Canon')
companies = [f'company_{i}' for i in range(200)]
model = QStandardItemModel(len(companies), 1)
model.setHorizontalHeaderLabels(['Company'])
for row, company in enumerate(companies):
item = QStandardItem(company)
model.setItem(row, 0, item)
filter_proxy_model = QSortFilterProxyModel()
filter_proxy_model.setSourceModel(model)
filter_proxy_model.setFilterCaseSensitivity(Qt.CaseInsensitive)
filter_proxy_model.setFilterKeyColumn(0)
search_field = QLineEdit()
search_field.textChanged.connect(filter_proxy_model.setFilterRegExp)
mainLayout.addWidget(search_field)
table = QTableView()
table.setStyleSheet('font-size: 35px;')
table.verticalHeader().setSectionResizeMode(QHeaderView.Stretch)
table.horizontalHeader().setSectionResizeMode(QHeaderView.Stretch)
table.setModel(filter_proxy_model)
mainLayout.addWidget(table)
self.setLayout(mainLayout)
app = QApplication(sys.argv)
demo = AppDemo()
demo.show()
sys.exit(app.exec_())
我自己找到了解决办法。我改为使用 QListWidget。但同样的逻辑也可以应用于 QListView。下面是代码。
下面是核心部分,是一个slot,接一个line edit。这样做,效率很好,特别是当你有很多项目时,因为当 lineedit 输入更改时它不使用 QListWidget.clear(),它只是将项目隐藏在幕后。
# deal with search file
def onFileTextChanged(self, text):
search_items = self.listWidget.findItems(text, Qt.MatchContains)
for index in range(self.listWidget.count()):
item = self.listWidget.item(index)
if item in search_items:
item.setHidden(False)
else:
item.setHidden(True)