Changing index in combobox delegate only calls setModelData after losing focus
Hi all, I hope you can help me with this problem.
I have a QTableView in which the first row contains comboboxes (>100). The comboboxes influence the rest of the contents of the QTableView.
I've noticed that the setModelData() method does get called (and the table gets properly updated), but not immediately after selecting a new item from the combobox, but you need to click somewhere else (lose focus) before it gets called. This is quite inconvenient, and I'd like to know how to skip that click.
My comboboxes are made by calling setItemDelegateForRow for the first row of the table. The implementation of createEditor, setEditorData and setModelData is standard. My comboboxdelegate is derived from QStyledItemDelegate. Here is my code from ComboboxDelegate.cpp:
Code:
MainComboBoxDelegate
::MainComboBoxDelegate(QObject *parent, MainTableListModel
*model
) : QStyledItemDelegate
(parent
){
m_model = model;
}
{
if(index.row() == 0 && index.column() != 0)
{
editor->setModel(m_model);
editor->setEditable(false);
return editor;
}
else
return QStyledItemDelegate::createEditor(parent, option, index);
}
{
if(index.row() == 0)
{
QString temp
= index.
model()->data
(index, Qt
::EditRole).
toString();
QComboBox *comboBox
= static_cast<QComboBox
*>
(editor
);
comboBox->setCurrentIndex(comboBox->findText(temp));
}
}
{
if(index.row() == 0)
{
QComboBox *comboBox
= static_cast<QComboBox
*>
(editor
);
QString value
= comboBox
->currentText
();
model->setData(index, value, Qt::EditRole);
}
}
{
editor->setGeometry(option.rect);
}
And this is how I create them in my view class:
Code:
ui->Main_Table_View->setItemDelegateForRow(0, new MainComboBoxDelegate(ui->Main_Table_View, Maintablelistmodel));
for(int i = 1; i < Maintablemodel->columnCount(); ++i)
ui->Main_Table_View->openPersistentEditor(Maintablemodel->index(0, i));
The Maintablelistmodel is a QSortFilterProxyModel which contains only one column.
As the comboboxes get created this way, it's hard to pick up signals from them manually, but it may be an option.
Is there something I'm doing wrong, or is it some kind of limitation? Am I missing something?
Any help is highly appreciated.
Re: Changing index in combobox delegate only calls setModelData after losing focus
Same problem here:
Code:
{
QVariant value
= index.
data(Qt
::EditRole);
QVariant::Type type
= index.
data(SensorPropertyModel
::PropertyTypeRole).
type();
switch(type) {
{
QComboBox* comboBox
= static_cast<QComboBox
*>
(editor
);
value = index.data(SensorPropertyModel::ListIndexRole);
comboBox->setCurrentIndex(value.toInt());
break;
}
default:
break;
}
}
Code:
void PropertyItemDelegate
::setModelData(QWidget* editor,
const QModelIndex& index) const
{
if(!index.isValid()) {
return;
}
QVariant value
= index.
data(Qt
::EditRole);
QVariant::Type type
= index.
data(SensorPropertyModel
::PropertyTypeRole).
type();
switch(type) {
{
QComboBox* comboBox
= static_cast<QComboBox
*>
(editor
);
value = comboBox->currentText();
int nValue = comboBox->currentIndex();
model->setData(index, nValue, SensorPropertyModel::ListIndexRole);
break;
}
default:
break;
}
model->setData(index, value, Qt::EditRole);
}
Any help is appreciated!
Added after 18 minutes:
Found a workaround:
Code:
{
QComboBox* comboBox
= static_cast<QComboBox
*>
(editor
);
value = index.data(SensorPropertyModel::ListIndexRole);
connect(comboBox, SIGNAL(currentIndexChanged(int)), this, SLOT(onCurrentIndexChanged(int)));
comboBox->setCurrentIndex(value.toInt());
break;
}
Notice the connect-line.
Code:
void PropertyItemDelegate::onCurrentIndexChanged(int nIndex)
{
QComboBox* cb
= static_cast<QComboBox
*>
(sender
());
if(cb) {
emit commitData(cb);
}
}
See here: http://qt-project.org/forums/viewthread/4531
Re: Changing index in combobox delegate only calls setModelData after losing focus
For me this worked too, but I had to put the connect into another method than setModelData, because that method is hit only when you click somewhere outside the combobox - which is part of the problem. Putting it in createEditor or setEditorData works.