使用Qt,让tableview分页处理,然后可以在文本框搜索数据
时间: 2024-03-20 12:45:30 浏览: 89
实现 QTableView 分页功能需要结合 QAbstractItemModel 和 QSortFilterProxyModel 来完成。具体实现步骤如下:
1. 自定义一个 QAbstractItemModel,用于实现数据的分页和加载。
2. 自定义一个 QSortFilterProxyModel,用于实现数据的过滤功能。
3. 将 QAbstractItemModel 和 QSortFilterProxyModel 组合起来,并将其设置为 QTableView 的 model。
4. 在需要进行搜索时,调用 QSortFilterProxyModel 的 setFilterRegExp() 方法设置过滤条件。
下面是一个简单的示例代码:
```python
from PyQt5.QtCore import QAbstractTableModel, QSortFilterProxyModel, Qt
from PyQt5.QtGui import QStandardItemModel
from PyQt5.QtWidgets import QApplication, QTableView, QLineEdit, QVBoxLayout, QWidget
class MyTableModel(QAbstractTableModel):
def __init__(self, parent=None):
super().__init__(parent)
self.data = []
self.current_page = 0
self.page_size = 10
def rowCount(self, parent=QModelIndex()):
return min(self.page_size, len(self.data) - self.current_page * self.page_size)
def columnCount(self, parent=QModelIndex()):
return len(self.data[0])
def data(self, index, role=Qt.DisplayRole):
if role == Qt.DisplayRole:
row = index.row() + self.current_page * self.page_size
col = index.column()
if row < len(self.data):
return self.data[row][col]
def load_data(self, data):
self.data = data
self.layoutChanged.emit()
def reset(self):
self.current_page = 0
self.layoutChanged.emit()
def next_page(self):
if self.current_page < len(self.data) // self.page_size:
self.current_page += 1
self.layoutChanged.emit()
def prev_page(self):
if self.current_page > 0:
self.current_page -= 1
self.layoutChanged.emit()
class MainWindow(QWidget):
def __init__(self):
super().__init__()
self.model = MyTableModel()
self.proxy_model = QSortFilterProxyModel()
self.proxy_model.setSourceModel(self.model)
self.table_view = QTableView()
self.table_view.setModel(self.proxy_model)
self.table_view.setSortingEnabled(True)
self.filter_edit = QLineEdit()
self.filter_edit.textChanged.connect(self.filter_changed)
self.prev_button = QPushButton('Prev')
self.prev_button.clicked.connect(self.prev_page)
self.next_button = QPushButton('Next')
self.next_button.clicked.connect(self.next_page)
layout = QVBoxLayout()
layout.addWidget(self.filter_edit)
layout.addWidget(self.table_view)
layout.addWidget(self.prev_button)
layout.addWidget(self.next_button)
self.setLayout(layout)
def load_data(self, data):
self.model.load_data(data)
self.model.reset()
def filter_changed(self, text):
self.proxy_model.setFilterRegExp(text)
self.proxy_model.invalidate()
def prev_page(self):
self.model.prev_page()
def next_page(self):
self.model.next_page()
if __name__ == '__main__':
app = QApplication([])
window = MainWindow()
window.show()
data = [
['John1', '20', 'Male'],
['John2', '21', 'Male'],
['John3', '22', 'Male'],
['John4', '23', 'Male'],
['John5', '24', 'Female'],
['John6', '25', 'Female'],
['John7', '26', 'Female'],
['John8', '27', 'Female'],
['John9', '28', 'Female'],
['John10', '29', 'Female'],
['John11', '30', 'Male'],
['John12', '31', 'Male'],
['John13', '32', 'Male'],
['John14', '33', 'Male'],
['John15', '34', 'Female'],
['John16', '35', 'Female'],
['John17', '36', 'Female'],
['John18', '37', 'Female'],
['John19', '38', 'Female'],
['John20', '39', 'Female'],
]
window.load_data(data)
app.exec_()
```
在这个示例中,我们自定义了一个 MyTableModel,用于实现数据的分页和加载。该 model 中有一个 data 属性用于存储所有数据,还有一个 current_page 属性用于记录当前页码。我们还定义了 load_data()、reset()、next_page() 和 prev_page() 四个方法,分别用于加载数据、重置分页、翻到下一页和翻到上一页。
然后我们将 MyTableModel 和 QSortFilterProxyModel 组合起来,并将其设置为 QTableView 的 model。我们还定义了一个 QLineEdit 和两个 QPushButton,用于搜索和翻页。在搜索时,我们调用 QSortFilterProxyModel 的 setFilterRegExp() 方法设置过滤条件。在翻页时,我们调用 MyTableModel 的 next_page() 和 prev_page() 方法进行分页。
需要注意的是,在 MyTableModel 中重写 rowCount() 方法时,需要将其返回值限制在每页最大行数以内。这样才能保证在分页时能够正确地显示数据。
阅读全文