Using a custom data type and editor in QStandardItemModel
-
wrote on 16 Oct 2019, 17:20 last edited by
I'm using a custom data type in the items of a QStandardItemModel, but setting item data for different roles seems to affect the data of all roles, and setting the text for the items seems to overwrite the data as well. What's the correct way of doing this?
-
How do you set the data? Please show some code.
-
How do you set the data? Please show some code.
wrote on 16 Oct 2019, 17:32 last edited by Lurkki@Christian-Ehrlicher
Setting the data initially:std::function<void(tc_assignable_node_t*, QStandardItem*)> traverse; traverse = [=, &traverse](tc_assignable_node_t *node, QStandardItem *item) { if (node == NULL) { return; } if (node->name != NULL) { qDebug() << node->name; } // List for adding the name and editor on the same row QList <QStandardItem*> rowItems; QStandardItem *nameItem = new QStandardItem; nameItem->setText(node->name); nameItem->setEditable(false); rowItems.append(nameItem); // Don't add editor item for TC_ASSIGNABLE_NONE nodes if (node->value_category != TC_ASSIGNABLE_NONE) { QStandardItem *editorItem = new QStandardItem; QVariant v; AssignableData data(node); v.setValue(data); editorItem->setData(v, Qt::EditRole); //editorItem->setText(node->name); rowItems.append(editorItem); } item->appendRow(rowItems); for (uint32_t i = 0; i < node->children_count; i++) { traverse(node->children_nodes[i], nameItem); } };
setModelData() of my delegate:
AssignableData data = qvariant_cast<AssignableData>(index.model()->data(index)); QVariant v; QStandardItemModel *s_model = static_cast<QStandardItemModel*>(model); ... IntRangeEditor *ed = static_cast<IntRangeEditor*>(editor); data.setValue(ed->value()); v.setValue(data); s_model->setData(index, v, Qt::EditRole); //s_model->itemFromIndex(index)->setText("");
without the last line uncommented, it seems to overwrite the item's entire data and it becomes ineditable
-
@Lurkki said in Using a custom data type and editor in QStandardItemModel:
without the last line uncommented,
You mean '//s_model->itemFromIndex(index)->setText("");' ?
This will set the Qt::DisplayRole and Qt::EditRole as explained in the documentation -
@Lurkki said in Using a custom data type and editor in QStandardItemModel:
without the last line uncommented,
You mean '//s_model->itemFromIndex(index)->setText("");' ?
This will set the Qt::DisplayRole and Qt::EditRole as explained in the documentationwrote on 16 Oct 2019, 19:16 last edited by@Christian-Ehrlicher s_model->setData(index,"a", Qt::DisplayRole); has the same effect, it overwrites my custom data
-
Hi
I might have missed something but i only see you using
Qt::EditRole
so where is this custom data stored and in what way
"becomes ineditable" its still shown but you can type in it or ? -
Hi
I might have missed something but i only see you using
Qt::EditRole
so where is this custom data stored and in what way
"becomes ineditable" its still shown but you can type in it or ? -
@Christian-Ehrlicher s_model->setData(index,"a", Qt::DisplayRole); has the same effect, it overwrites my custom data
@Lurkki said in Using a custom data type and editor in QStandardItemModel:
has the same effect, it overwrites my custom data
I would say it's a bug if it's not - see the documentation...
Note: The default implementation treats Qt::EditRole and Qt::DisplayRole as referring to the same data.
-
@Lurkki said in Using a custom data type and editor in QStandardItemModel:
has the same effect, it overwrites my custom data
I would say it's a bug if it's not - see the documentation...
Note: The default implementation treats Qt::EditRole and Qt::DisplayRole as referring to the same data.
wrote on 16 Oct 2019, 20:58 last edited by Lurkki@Christian-Ehrlicher How should I go about subclassing QStandardItem and reimplementing setData then? I can't seem to find much information about it.
-
@Christian-Ehrlicher How should I go about subclassing QStandardItem and reimplementing setData then? I can't seem to find much information about it.
Hi
Can you please make a small example showing this ?,I have a bad feeling its just incorrect use / expectations and
not an actual bug.Qt::EditRole and Qt::DisplayRole is the same so that is expected.
try to use Qt::UserRole for your custom data end see.
To use custom data, you can use
setData(index,"a", Qt::UserRole );
setData(index,"a", Qt::UserRole +1);
setData(index,"a", Qt::UserRole +2); -
Hi
Can you please make a small example showing this ?,I have a bad feeling its just incorrect use / expectations and
not an actual bug.Qt::EditRole and Qt::DisplayRole is the same so that is expected.
try to use Qt::UserRole for your custom data end see.
To use custom data, you can use
setData(index,"a", Qt::UserRole );
setData(index,"a", Qt::UserRole +1);
setData(index,"a", Qt::UserRole +2);wrote on 24 Oct 2019, 11:46 last edited by Lurkki@mrjj Thanks, that works for my use case
Setting the data:
if (node->value_category != TC_ASSIGNABLE_NONE) { QStandardItem *editorItem = new QStandardItem; QVariant v; AssignableData data(node); v.setValue(data); editorItem->setData(v, Qt::UserRole); //editorItem->setText(node->name); rowItems.append(editorItem); }
Setting editor data in the delegate:
void AssignableEditorDelegate::setEditorData(QWidget* editor, const QModelIndex &index) const { AssignableData data = qvariant_cast<AssignableData>(index.model()->data(index, Qt::UserRole)); switch (data.m_valueCategory) { case TC_ASSIGNABLE_RANGE: switch (data.m_rangeInfo.range_data_type) { case TC_ASSIGNABLE_RANGE_INT: { IntRangeEditor *ed = static_cast<IntRangeEditor*>(editor); ed->setValue(data.value().toInt()); break; } default: break; } default: break; } }
Setting model data:
void AssignableEditorDelegate::setModelData(QWidget *editor, QAbstractItemModel *model, const QModelIndex &index) const { AssignableData data = qvariant_cast<AssignableData>(index.model()->data(index, Qt::UserRole)); QVariant v; QStandardItemModel *s_model = static_cast<QStandardItemModel*>(model); switch (data.m_valueCategory) { ... case TC_ASSIGNABLE_RANGE: switch (data.m_rangeInfo.range_data_type) { case TC_ASSIGNABLE_RANGE_INT: { IntRangeEditor *ed = static_cast<IntRangeEditor*>(editor); data.setValue(ed->value()); v.setValue(data); s_model->setData(index, v, Qt::UserRole); s_model->setData(index, ed->value(), Qt::DisplayRole); break; } default: break; } default: break; } }
I also had to do
setAutoFillBackground(true);
in my editor widget to make the display text not overlap with the editor.
1/11