Search code examples
pythonqtpysideqtableviewdatamodel

editing QTableView cell value


how could i make QTableView cell keep its original value when editing it? when i start editing cell it is cleared out automatically. I searched all over the place and i can not find any pointers that would lead somewhere. My implementation of model view:

class BlockViewModel(QAbstractTableModel):

    def __init__(self, structure, data):
        QAbstractTableModel.__init__(self)
        self._data = data
        self._struct = structure

        for i, s in enumerate(structure):
            cmnt = s['comment']
            name = cmnt if cmnt else s['name']
            self.setHeaderData(i, Qt.Horizontal, name)

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

    def columnCount(self, parent = QModelIndex()):
        return len(self._struct)

    def data(self, index, role):
        if role == Qt.DisplayRole:
            try:
                row = index.row()
                col = index.column()
                name = self._struct[col]['name']
                return self._data[row][name]
            except:
                pass
        elif role == Qt.CheckStateRole:
            return None

        return None

    def flags(self, index):
        flags = super(self.__class__,self).flags(index)

        flags |= Qt.ItemIsEditable
        flags |= Qt.ItemIsSelectable
        flags |= Qt.ItemIsEnabled
        flags |= Qt.ItemIsDragEnabled
        flags |= Qt.ItemIsDropEnabled

        return flags

    def headerData(self, section, orientation, role = Qt.DisplayRole):
        if role != Qt.DisplayRole:
            return None

        if orientation == Qt.Horizontal:
            cmnt = self._struct[section]['comment']
            return cmnt if cmnt else self._struct[section]['name']
        else:
            return str(section)

    def setData(self, index, value, role=Qt.EditRole):
        row = index.row()
        col = index.column()
        name = self._struct[col]['name']
        self._data[row][name] = value
        self.emit(SIGNAL('dataChanged()'))
        return True

Solution

  • The data method is responsible for displaying your data all the time. While editing, it uses EditRole. So modify your data method to show values in EditRole same as DisplayRole like below:

    def data(self, index, role):
        if role == Qt.DisplayRole or role == Qt.EditRole:
            try:
                row = index.row()
                col = index.column()
                name = self._struct[col]['name']
                return self._data[row][name]
            except:
                pass
        elif role == Qt.CheckStateRole:
            return None
    
        return None