QStandardItemModel doesn't update QTableView
-
class EventsTableModel(QStandardItemModel): EVENT = 1000 def __init__(self, et: EventTree, show_only: list[EventEnum]) -> None: super().__init__(None) self.et = et self.events = tuple(et.get(*show_only)) self.set_horizontal_header_labels(["ID", "Value"]) for event in self.events: id_item = QStandardItem(str(event.id)) id_item.set_editable(False) val_item = QStandardItem() val_item.set_data(event, self.EVENT) try: val_item.set_data(event.value, Qt.ItemDataRole.DisplayRole) except NotImplementedError: continue self.append_row((id_item, val_item)) def set_data(self, index: QModelIndex, value, role: int = ...) -> bool: event = index.data(self.EVENT) try: event.value = value except Exception as exc: logging.exception(exc) return False else: self.dataChanged.emit(index, index) # type: ignore return True
When I try to enter a new value in a cell's editor and press Enter, the new value doesn't appear in the cell. This occurs even if there are no exceptions.
I am using a normal QTableView instance for this model. The data gets correctly displayed initially after loading.
PySide: 6.4.2
EDIT: Fixed it by adding this line before emitting
dataChanged
:self.item_from_index(index).set_data(value, Qt.ItemDataRole.DisplayRole)
-
-
@demberto
Yourset_data()
method does not use therole
parameter passed to it, which it should, or you should not have it accept such a parameter.
If you do make it use the parameter, you should be passingQt.ItemDataRole.EditRole
notDisplayRole
. -
@JonB Do you mean the place where I call
self.item_from_index(index).set_data(value, Qt.ItemDataRole.DisplayRole)
?OR do you mean this?
def set_data(self, index: QModelIndex, value, role: int = ...) -> bool: event = index.data(self.EVENT) try: event.value = value except Exception as exc: logging.exception(exc) return False else: self.item_from_index(index).set_data(value, role) self.dataChanged.emit(index, index) # type: ignore return True
EDIT: That works
I still don't understand why I have to callself.item_from_index(index).set_data(value, role)
explicitly. Isn't that whatset_data
mechanism is supposed to do internally, or I should call super-classset_data
in myelse
clause? -
@demberto
Yes, you should call baseQStandardItemModel.setData()
to handle the case you don't.Your code is bad for the normal, successful case. You do not return
True
, you just drop off the end of the method and Python will doubtless returnNone
/False
, could be a problem.The base
setData()
defaultsrole = EditRole
for the parameter. You really ought do so too.Where you call it you show
self.item_from_index(index).set_data(value, Qt.ItemDataRole.DisplayRole)
. That should really beEditRole
, or you can omit it if you change to default as per previous point. -
@JonB Finally:
Your code is bad for the normal, successful case. You do not return True, you just drop off the end of the method and Python will doubtless return None/False, could be a problem.
def set_data(self, index: QModelIndex, value, role: int = Qt.ItemDataRole.EditRole) -> bool: event = index.data(self.EVENT) try: event.value = value except Exception as exc: logging.exception(exc) return False else: super().set_data(index, value, role) return True
Thanks!