Это можно сделать путем создания подкласса QAbstractTableModel
для создания пользовательской модели таблицы, которая использует базовый фрейм данных для передачи данных в QTableView
. Затем эту пользовательскую модель можно комбинировать с QProxyFilterSortModel
для фильтрации данных в таблице. Чтобы создать настраиваемую нередактируемую модель из QAbstractTableModel
, вам необходимо реализовать как минимум rowCount
, columnCount
, data
и headerData
. В этом случае минимальная реализация может быть примерно такой:
class DataFrameModel(QtCore.QAbstractTableModel):
def __init__(self, data_frame, parent = None):
super().__init__(parent)
self.data_frame = data_frame
def rowCount(self, index):
if index.isValid():
return 0
return self.data_frame.shape[0]
def columnCount(self, index):
if index.isValid():
return 0
return self.data_frame.shape[1]
def data(self, index, role):
if not index.isValid() or role != QtCore.Qt.DisplayRole:
return None
return str(self.data_frame.iloc[index.row(), index.column()])
def headerData(self, section, orientation, role=None):
if role != QtCore.Qt.DisplayRole:
return None
if orientation == QtCore.Qt.Vertical:
return self.data_frame.index[section]
else:
return self.data_frame.columns[section]
Чтобы отобразить и отфильтровать данные в таблице, вы можете сделать что-то вроде этого:
class MyWidget(QtWidgets.QWidget):
def __init__(self, parent = None):
super().__init__(parent)
self.table_view = QtWidgets.QTableView()
self.proxy_model = QtCore.QSortFilterProxyModel()
# by default, the QSortFilterProxyModel will search for keys in the first column only
# setting QSortFilterProxyModel.filterKeyColumn to -1 will match values in all columns
self.proxy_model.setFilterKeyColumn(-1)
self.table_view.setModel(self.proxy_model)
# line edit for entering (part of) the key that should be searched for
self.line_edit = QtWidgets.QLineEdit()
self.line_edit.textChanged.connect(self.filter_text)
vlayout = QtWidgets.QVBoxLayout(self)
vlayout.addWidget(self.line_edit)
vlayout.addWidget(self.table_view)
def filter_text(self, text):
self.proxy_model.setFilterFixedString(text)
def set_data(self, data):
self.model = DataFrameModel(pd.DataFrame(data))
self.proxy_model.setSourceModel(self.model)
if __name__ == "__main__":
app = QtWidgets.QApplication([])
win = MyWidget()
win.set_data({'a':['apple', 'banana', 'cherry'], 'b':[4,5,6], 'c':['green', 'yellow', 'red']})
win.show()
app.exec()
Конечно, это очень простая реализация c, но я могу помочь вам начать работу.