PDA

View Full Version : About QComboBox::currentIndexChanged



aresa
3rd December 2013, 06:28
Hi all,
I use QStandardItemModel/QTableView/QItemDelegate in my app.
QComboBox is one of the columns and it is made shown for all the time using QTableView::openPersistentEditor.

i need:
1. when user clicks the QCombox and change the current index, i notify the new change to the model while the current index stays unchaged until the model is updated.
2. i want to get notified as soon as user changes the current index. while the problem is QItemDelegate::setModelData is never called until the QComboBox is focused out.

i tried this:
void
MyItemDelegate::createEditor(..)
{
QComboBox * comboEditor = new QComboBox(parent);

comboEditor->addItem("1");
comboEditor->addItem("2");

connect(comboEditor, SIGNAL(currentIndexChanged(int)), this, SLOT(emitDataCommit(int)));

return comboEditor;
}

void
MyItemDelegate::emitDataCommit(int)
{
emit commitData(qobject_cast<QWidget *>(sender()));
}

void
MyItemDelegate::setModelData(QWidget *editor, QAbstractItemModel *model, const QModelIndex &index) const
{
QComboBox *comboBox = qobject_cast<QComboBox*>(editor);
Q_ASSERT(comboBox);

QString newText = comboBox->currentText();

/// set it back to the previous until the model is updated using the new data.
/// and the current index is automatically updated by the model when it is finished updating.
if (newText == "1")
{
comboBox->setCurrentText("2");
}
else if (newText == "2")
{
comboBox->setCurrentText("1");
}

model->setData(index, newText);
}


BUT when the model accepts the new data and call setData() to update itself, the signal comboEditor::currentIndexChanged(int) is emitted for the second time by the model and MyItemDelegate::setModelData is called again.....

is there anyway to prevent the model from emiting the signal or is there anyway to distinguish the two call to MyItemDelegate::setModelData?

anda_skoa
3rd December 2013, 10:30
You could try blocking the combobox signals in setModelData until you've returned from model->setData()

See QObject::blockSignals()

Cheers,
_

aresa
3rd December 2013, 12:38
You could try blocking the combobox signals in setModelData until you've returned from model->setData()

See QObject::blockSignals()

Cheers,
_

Thank you, but i override setData in QStandardItemModel, and it
Only send a command to the server via the web and returns afterwards.
So it is not until the server notifies me of the result that i call
Qstandarditemmodel::setData to update the model.

anda_skoa
3rd December 2013, 13:22
Ah, I see. Since you were using QStandardItemModel I assumed it had all data itself. Something like that is usually done via a custom model.

Anyway, block the signal when "resetting" the comboBox. Right now you commit twice, once when the user changes the value and once when your "reset".
And maybe when setEditorData() changes the content. After all there is no point in notifying the model about data it provided itself.

Cheers,
_

aresa
4th December 2013, 02:01
I googled for hours and found a nice signal called 'activated' ,
This signal is only emitted when the current index is set by user click.
Not pragmatically. So by connecting this with 'emitDataChanged' the second
Call to QItemDelegate::setModelData is effectively avoided.
This is almost what i want except that the 'actived' signal is also
Emitted even if the current index is not changed by user click.
Anyway this is easy to handle.

Thanks for your replies, happy programming with you.