2016-12-16 13 views
0

В моем файле графического интерфейса я создаю QTableView следующим образом (это та часть, которая автоматически генерируется Qt Designer):Сделать QTableView редактируемого когда модель панда dataframe

self.pnl_results = QtGui.QTableView(self.tab_3) 
font = QtGui.QFont() 
font.setPointSize(7) 
self.pnl_results.setFont(font) 
self.pnl_results.setFrameShape(QtGui.QFrame.StyledPanel) 
self.pnl_results.setFrameShadow(QtGui.QFrame.Sunken) 
self.pnl_results.setEditTriggers(QtGui.QAbstractItemView.AllEditTriggers) 
self.pnl_results.setShowGrid(True) 
self.pnl_results.setSortingEnabled(True) 
self.pnl_results.setCornerButtonEnabled(True) 
self.pnl_results.setObjectName("pnl_results") 

Я тогда определить модель, которая позволяет мне связать панд dataframe с QTableView:

class PandasModel(QtCore.QAbstractTableModel): 
    """ 
    Class to populate a table view with a pandas dataframe 
    """ 

    def __init__(self, data, parent=None): 
     QtCore.QAbstractTableModel.__init__(self, parent) 
     self._data = data 

    def rowCount(self, parent=None): 
     return len(self._data.values) 

    def columnCount(self, parent=None): 
     return self._data.columns.size 

    def data(self, index, role=QtCore.Qt.DisplayRole): 
     if index.isValid(): 
      if role == QtCore.Qt.DisplayRole: 
       return str(self._data.values[index.row()][index.column()]) 
     return None 

    def headerData(self, col, orientation, role): 
     if orientation == QtCore.Qt.Horizontal and role == QtCore.Qt.DisplayRole: 
      return self._data.columns[col] 
     return None 

    def setData(self, index, value, role): 
     if not index.isValid(): 
      return False 
     if role != QtCore.Qt.EditRole: 
      return False 
     row = index.row() 
     if row < 0 or row >= len(self._data.values): 
      return False 
     column = index.column() 
     if column < 0 or column >= self._data.columns.size: 
      return False 
     self._data.values[row][column] = value 
     self.dataChanged.emit(index, index) 
     return True 

    def flags(self, index): 
     flags = super(self.__class__,self).flags(index) 
     flags |= QtCore.Qt.ItemIsEditable 
     flags |= QtCore.Qt.ItemIsSelectable 
     flags |= QtCore.Qt.ItemIsEnabled 
     flags |= QtCore.Qt.ItemIsDragEnabled 
     flags |= QtCore.Qt.ItemIsDropEnabled 
     return flags 

и, наконец, добавить мой панд dataframe (DF) модели:

model = PandasModel(df) 
self.ui.pnl_results.setModel(model) 

Это правильно отображает мой кадр данных pandas в QTableView. Однако по какой-то причине, когда я редактирую файлы, возвращаем их исходные значения (а также после того, как я редактирую поле, оно начинается как пустое). Как я могу сделать его редактируемым, а затем написать результаты обратно в рамку данных pandas?

ответ

3

Ваша модель не имеет setData способ. Реализация по умолчанию от QtCore.QAbstractTableModel ничего не делает и возвращает False. Вам необходимо реализовать этот метод в своей модели, чтобы сделать его элементы доступными для редактирования. Если df является фактическим контейнером, хранящим данные, вы должны просто изменить значение элемента, хранящегося в контейнере, в методе setData. Это может выглядеть следующим образом:

def setData(self, index, value, role): 
    if not index.isValid(): 
     return False 
    if role != QtCore.Qt.EditRole: 
     return False 
    row = index.row() 
    if row < 0 or row >= len(self._data.values): 
     return False 
    column = index.column() 
    if column < 0 or column >= self._data.columns.size: 
     return False 
    self._data.values[row][column] = value 
    self.dataChanged.emit(index, index) 
    return True 

Кроме того, необходимо реализовать flags метод возвращает значение, содержащее QtCore.Qt.ItemIsEditable.

+0

Можете ли вы привести пример, как должен выглядеть метод setData? – Nickpick

+0

Хорошо, добавил пример реализации. – Dmitry

+0

Я изменил свой вопрос до последней версии, проблема в том, что отредактированные файлы, похоже, не распространяются на фреймворк данных, и как только я нажму, введите значения, возвращаемые исходным значениям. – Nickpick