将dataframe数据加入到pyqt5 tableview中,多线程加载方式,并要求tableview中每列都有有筛选功能,筛选出满足条件的行,且能进行数学筛选,要求用QStandardItemModel
时间: 2024-06-12 15:06:41 浏览: 145
Python Pandas中Dataframe对象,如何根据列值筛选满足条件的行,并且获得行的索引值
以下是一个示例代码,其中数据加载和筛选使用了多线程,数据存储在QStandardItemModel中,每列都有筛选功能,可以进行数学筛选。
```python
import sys
import pandas as pd
from PyQt5.QtWidgets import QApplication, QMainWindow, QTableView, QHeaderView, QComboBox, QLineEdit, QHBoxLayout, QWidget
from PyQt5.QtCore import Qt, QThread, pyqtSignal, QModelIndex
from PyQt5.QtGui import QStandardItemModel, QStandardItem
class LoadDataThread(QThread):
loaded = pyqtSignal(pd.DataFrame)
def __init__(self, parent=None):
super().__init__(parent)
def run(self):
data = pd.read_csv('data.csv')
self.loaded.emit(data)
class TableView(QTableView):
def __init__(self, parent=None):
super().__init__(parent)
self.setSortingEnabled(True)
self.setSelectionBehavior(QTableView.SelectRows)
self.setSelectionMode(QTableView.SingleSelection)
self.setEditTriggers(QTableView.NoEditTriggers)
self.horizontalHeader().setSectionResizeMode(QHeaderView.Stretch)
self.filter_widgets = []
self.filter_values = []
def setModel(self, model):
super().setModel(model)
self.filter_widgets = [None] * model.columnCount()
self.filter_values = [None] * model.columnCount()
for i in range(model.columnCount()):
self.filter_widgets[i] = QWidget(self)
layout = QHBoxLayout(self.filter_widgets[i])
layout.setContentsMargins(0, 0, 0, 0)
layout.setAlignment(Qt.AlignLeft)
combo = QComboBox(self.filter_widgets[i])
combo.addItems(['', '>', '>=', '=', '<=', '<'])
combo.currentIndexChanged.connect(lambda state, index=i: self.filter_changed(index))
layout.addWidget(combo)
line_edit = QLineEdit(self.filter_widgets[i])
line_edit.textChanged.connect(lambda text, index=i: self.filter_changed(index))
layout.addWidget(line_edit)
self.setIndexWidget(model.index(0, i), self.filter_widgets[i])
def filter_changed(self, column):
combo = self.filter_widgets[column].layout().itemAt(0).widget()
line_edit = self.filter_widgets[column].layout().itemAt(1).widget()
operator = combo.currentText()
value = line_edit.text()
self.filter_values[column] = (operator, value)
model = self.model()
for i in range(model.rowCount()):
if self.filter_row(i):
self.setRowHidden(i, False)
else:
self.setRowHidden(i, True)
def filter_row(self, row):
model = self.model()
for i in range(model.columnCount()):
value = model.data(model.index(row, i))
if self.filter_values[i]:
operator, filter_value = self.filter_values[i]
if operator == '>':
if not pd.isna(value) and float(value) > float(filter_value):
continue
else:
return False
elif operator == '>=':
if not pd.isna(value) and float(value) >= float(filter_value):
continue
else:
return False
elif operator == '=':
if str(value) == str(filter_value):
continue
else:
return False
elif operator == '<=':
if not pd.isna(value) and float(value) <= float(filter_value):
continue
else:
return False
elif operator == '<':
if not pd.isna(value) and float(value) < float(filter_value):
continue
else:
return False
return True
class MainWindow(QMainWindow):
def __init__(self, parent=None):
super().__init__(parent)
self.table_view = TableView(self)
self.setCentralWidget(self.table_view)
self.load_data_thread = LoadDataThread(self)
self.load_data_thread.loaded.connect(self.load_data)
self.load_data_thread.start()
def load_data(self, data):
model = QStandardItemModel(data.shape[0], data.shape[1])
for i in range(data.shape[0]):
for j in range(data.shape[1]):
item = QStandardItem(str(data.iloc[i, j]))
model.setItem(i, j, item)
self.table_view.setModel(model)
if __name__ == '__main__':
app = QApplication(sys.argv)
main_window = MainWindow()
main_window.show()
sys.exit(app.exec_())
```
阅读全文