In my project, I subclassed QStyledItemDelegate and returned a custom editor from the createEditor function.
QWidget* TagEditDelegate::createEditor(QWidget *parent, const QStyleOptionViewItem &option, const QModelIndex &index) const
{
TagEditWidget* tagEditWidget = new TagEditWidget(parent, index.data(Qt::UserRole+4).toInt(), index.data(Qt::UserRole+2).toByteArray(), index.data(Qt::UserRole+3).toByteArray(), index.parent().data(Qt::UserRole+4).toInt() == 9, parent->width());
return tagEditWidget; //tagEditWidget is my custom QWidget
}
When the editing finishes, I want to write the new data back to the model. So I overrode setModelData.
void TagEditDelegate::setModelData(QWidget * editor, QAbstractItemModel * model, const QModelIndex & index) const
{
TagEditWidget * tagEditWidget = qobject_cast<TagEditWidget*>(editor);
if (!tagEditWidget)
{
QStyledItemDelegate::setModelData(editor, model, index);
return;
}
//Edit model here?
}
This works, but the problem is that setModelData gets called no matter HOW the editor was closed. I only want to write the new data if the editor closed using the EndEditHint, QAbstractItemDelegate::SubmitModelCache. So I connected the closeEditor signal to a slot I made called editFinished.
connect(this, SIGNAL(closeEditor(QWidget*,QAbstractItemDelegate::EndEditHint)), this, SLOT(editFinished(QWidget*,QAbstractItemDelegate::EndEditHint)));
So now I am able to see HOW the editor closed via the EndEditHint and if I should write the data back to the model. Buuuuut, setModelData get's called BEFORE the closeEditor signal. How does one write the data back to the model when the closeEditor signal gets called last? Am I missing something here?
Basic answer:
Your concept seems good almost till the end. I would focus on the
TagEditDelegate::setModelDatamethod.If you actually don't want to update data in the model just check that it didn't change. Meaning that when
oldData == newDatajustreturn;and skip model updates.Additional notes:
Looking at your editor creation I get the impression that it doesn't hold a single value which is presented to the user. To make passing the argument more friendly and comparing the editor data easier consider creating a separate
class/structfor it. So you could call:where EditorData would be your class/struct which might be acquired by a separate function:
The function could be reused in the
setModelDatamethod to check the condition:Also avoid using magic numbers like
Qt::UserRole+2. Create your own enum to specify the required roles. For example:EDIT according to the discussion in the comments
If what you want is to discover whether user actually didn't cancel the edition one way or the other, you could override
eventFiltereither inside the editor or the delegate. When creating editor callinstallEventFilterin the constructor. YoureventFilterimplementation could look like this:Where
submittedis abooleditor member initialized tofalsein constructor. Then you could create a getter methodisSubmitted()and you are ready to check the status insidesetModelDatamethod.