I wrote a custom data model for display with several QTableViews.
Technically, everything works fine: my views show the changes made from my model. My data model is editable, and the setData() method emits a dataChanged() signal and returns true in a successful release.
However, my problem is that I need to move the mouse over the QTableView so that it displays the actual change, while I would like all the views to display the changes when they were made, without having to interact with the views to update them.
Any idea? Thanks,
It may be worth mentioning that I do not use the default role Qt::EditRole for editing data, but rather a user-defined enumeration value (named ActiveRole ).
Here's what I'm looking for: my data model contains properties on how to display the data used to create the style sheets that are served in viewS.
Thus, when changing the model for each view, all its elements are affected, therefore, the signal dataChanged() sent with indices covering all cells.
I also tried emitting layoutChanged() , but it doesn't seem to change the behavior in my case.
Here is an excerpt from the setData() method:
bool DataModel::setData(QModelIndex const& idx, QVariant const& value, int role) { if (ActiveRole == role) {
Here is an example of the data() method:
QVariant DataModel::data(QModelIndex const& idx, int role) const { if (ActiveRole == role) { boost::uuids::uuid id; return qVariantFromValue(id); } return QVariant(); }
And flags() points to the model being edited:
Qt::ItemFlags DataModel::flags(QModelIndex const& idx) const { if (false == idx.isValid()) { return Qt::ItemIsEditable; } return QAbstractTableModel::flags(idx) | Qt::ItemIsEditable; }
I have a user delegate that relies heavily on this SO stream to override the paint and sizeHint for drawing a QTextDocument addition, it provides ActiveRole content ActiveRole editor in setEditorData and calls DataMode::setData in setModelData :
void DataModelDelegate::setEditorData(QWidget* editor, QModelIndex const& idx) const { auto active = qVariantValue<boost::uuids::uuid>(idx.data(ActiveRole)); static_cast<DataModelEditor*>(editor)->setActive(active); } void DataModelDelegate::setModelData(QWidget* editor, QAbstractItemModel* model, QModelIndex const& idx) const { auto active = static_cast<DataModelEditor*>(editor)->getActive(); model->setData(idx, qVariantFromValue(active), ActiveRole); }
In createEditor() I connect a signal from the editor to my delegate slot for data transfer:
QWidget* DataModelDelegate::createEditor(QWidget* parent, QStyleOptionViewItem const& option, QModelIndex const& idx) const { auto editor = new DataModelEditor(parent); connect(editor, SIGNAL(activeItem()), this, SLOT(commitEditorData())); return editor; }
When you click on an element, the editor fires an activeItem signal; the connected commitEditorData slot in turn triggers a commitData signal with an editor argument.
Thus, all my views use these custom delegation, editor, and data functions. The view I'm interacting with does show changes, but for other views, the mouse needs to vibrate over them to show the changes.