Hi all 
I am trying to customize my QTreeView to get an editable QComboBox into a column.
There are some example on the Net, but I haven't seen any with an editable QComboBox, and mine does not work properly...
Let me explain : if I click into the cell and select an item from the list it works : the selection is saved. But if I enter free text and change the focus, then the text is lost, and my DisplayRole role contains nothing. But if I enter some text again, then it will be saved...
I searched without success some hours but didn't find any clue, so I'm posting here, maybe someone has a good idea about this...
Now, some code :
{
comboBox->setEditable(true);
comboBox
->setInsertPolicy
(QComboBox::NoInsert);
comboBox->addItems(index.model()->data(index, CustomRoles::ValueRole).toStringList());
connect(comboBox, SIGNAL(activated(int)), this, SLOT(emitCommitData()));
connect(comboBox->lineEdit(), SIGNAL(editingFinished()), this, SLOT(emitCommitData()));
QString currentText
= index.
model()->data
(index, Qt
::DisplayRole).
toString();
int selectedItem = comboBox->findText(currentText);
if(selectedItem == -1)
comboBox->setEditText(index.model()->data(index, Qt::DisplayRole).toString());
else
comboBox->setCurrentIndex(selectedItem);
return comboBox;
}
QWidget *ActionDelegate::createEditor(QWidget *parent, const QStyleOptionViewItem &option, const QModelIndex &index) const
{
QComboBox *comboBox = new QComboBox(parent);
comboBox->setEditable(true);
comboBox->setInsertPolicy(QComboBox::NoInsert);
comboBox->addItems(index.model()->data(index, CustomRoles::ValueRole).toStringList());
connect(comboBox, SIGNAL(activated(int)), this, SLOT(emitCommitData()));
connect(comboBox->lineEdit(), SIGNAL(editingFinished()), this, SLOT(emitCommitData()));
QString currentText = index.model()->data(index, Qt::DisplayRole).toString();
int selectedItem = comboBox->findText(currentText);
if(selectedItem == -1)
comboBox->setEditText(index.model()->data(index, Qt::DisplayRole).toString());
else
comboBox->setCurrentIndex(selectedItem);
return comboBox;
}
To copy to clipboard, switch view to plain text mode
{
QComboBox *comboBox
= qobject_cast<QComboBox
*>
(editor
);
comboBox->clear();
comboBox->addItems(index.model()->data(index, CustomRoles::ValueRole).toStringList());
QString currentText
= index.
model()->data
(index, Qt
::DisplayRole).
toString();
int selectedItem = comboBox->findText(currentText);
if(selectedItem == -1)
comboBox->setEditText(index.model()->data(index, Qt::DisplayRole).toString());
else
comboBox->setCurrentIndex(selectedItem);
}
void ActionDelegate::setEditorData(QWidget *editor, const QModelIndex &index) const
{
QComboBox *comboBox = qobject_cast<QComboBox*>(editor);
comboBox->clear();
comboBox->addItems(index.model()->data(index, CustomRoles::ValueRole).toStringList());
QString currentText = index.model()->data(index, Qt::DisplayRole).toString();
int selectedItem = comboBox->findText(currentText);
if(selectedItem == -1)
comboBox->setEditText(index.model()->data(index, Qt::DisplayRole).toString());
else
comboBox->setCurrentIndex(selectedItem);
}
To copy to clipboard, switch view to plain text mode
{
QComboBox* comboBox
= qobject_cast<QComboBox
*>
(editor
);
for(int i=0;i<comboBox->count();++i)
value.append(comboBox->itemText(i));
int selectedItem = comboBox->findText(comboBox->currentText());
if(selectedItem == -1)
{
model->setData(index, -1, CustomRoles::SelectedItemRole);
model->setData(index, comboBox->currentText(), Qt::DisplayRole);
}
else
{
model->setData(index, selectedItem, CustomRoles::SelectedItemRole);
model->setData(index, comboBox->itemText(selectedItem), Qt::DisplayRole);
}
model->setData(index, value, CustomRoles::ValueRole);
}
void ActionDelegate::setModelData(QWidget *editor, QAbstractItemModel *model, const QModelIndex &index) const
{
QComboBox* comboBox = qobject_cast<QComboBox*>(editor);
QStringList value;
for(int i=0;i<comboBox->count();++i)
value.append(comboBox->itemText(i));
int selectedItem = comboBox->findText(comboBox->currentText());
if(selectedItem == -1)
{
model->setData(index, -1, CustomRoles::SelectedItemRole);
model->setData(index, comboBox->currentText(), Qt::DisplayRole);
}
else
{
model->setData(index, selectedItem, CustomRoles::SelectedItemRole);
model->setData(index, comboBox->itemText(selectedItem), Qt::DisplayRole);
}
model->setData(index, value, CustomRoles::ValueRole);
}
To copy to clipboard, switch view to plain text mode
void ActionDelegate::emitCommitData()
{
emit commitData(qobject_cast<QWidget *>(sender()));
}
void ActionDelegate::emitCommitData()
{
emit commitData(qobject_cast<QWidget *>(sender()));
}
To copy to clipboard, switch view to plain text mode
CustomRoles::SelectedItemRole represents the currently selected item, or -1 if it's free text
CustomRoles::ValueRole represents all the items of the combo box
Bookmarks