PDA

View Full Version : QComboBox roles question



mentalmushroom
26th April 2012, 12:30
I am trying to understand how data roles are used by QComboBox class. I want to add items that are displayed in one way, but edited in another way, e.g. item is displayed as "Item 1", but when I select it, it should be placed to the edit field as "1". I tried to use Qt::DisplayRole and Qt::EditRole, but I noticed something strange: it seems like values are displayed for the role I used for the last time. In following example items are shown for the EditRole, even if I set combobox as not editable, but it worth to swap those two lines and DisplayRole will be used everywhere, even in the edit field. Could somebody explain me thing behavior?



#include <QtCore>
#include <QApplication>
#include <QtGui>

int main(int argc, char *argv[])
{
QApplication a(argc, argv);

QComboBox comboBox;
comboBox.setEditable(true);

for (int i = 0; i<3; ++i)
{
comboBox.addItem(QString("item %1").arg(i));

comboBox.setItemData(i, QString("display %1").arg(i), Qt::DisplayRole);
comboBox.setItemData(i, i, Qt::EditRole);
}

comboBox.show();

return a.exec();
}

viulskiez
26th April 2012, 15:12
I think the rules applied to QComboBox similar for all subclass of QAbstractItemView even QComboBox doesn't inherit QAbstractItemView, but It is by default, internally use QStandardItemModel and QComboBoxListView. Try to debug this after adding item and you'll get better understanding:

qDebug() << comboBox->model();
qDebug() << comboBox->view();

mentalmushroom
26th April 2012, 15:21
Honestly, I don't understand your suggestion. The following debug lines do not give me any useful info about data roles and why DisplayRole is used instead of EditRole and vice versa.

viulskiez
26th April 2012, 15:33
It is using Model/View convention.

mentalmushroom
26th April 2012, 16:40
Maybe I was not clear in asking my question. I am wondering why it shows EditRole data when I was expected to see DiplayRole data (in the drop down list, for example) or why does it show DisplayRole data in the edit field, moreover, I have different results depending on the order of data assignment to EditRole and DisplayRole. If you swap 16th and 17th line of my code you will get different results, that appears to be strange to me. Where model/view convention explains this?

norobro
26th April 2012, 23:44
Sometimes you really have to dig around in the docs to find answers ;)

From QComboBox
By default a QStandardItemModel stores the items . . .
Then from QStandardItem::setData() (http://qt-project.org/doc/qt-4.8/qstandarditem.html#setData):
Note: The default implementation treats Qt::EditRole and Qt:: DisplayRole as referring to the same data.

viulskiez
27th April 2012, 06:30
Where model/view convention explains this?
noboro was right. You can look into the source (http://qt.gitorious.org/qt/qt/blobs/4.8/src/gui/itemviews/qstandarditemmodel.cpp), at line 808.

mentalmushroom
27th April 2012, 07:02
Thanks, guys. Now it's clear, but how can I change this behavior?

viulskiez
27th April 2012, 07:23
I suggest to subclass QStandardItem then set it as item prototype (QStandardItemModel::setItemPrototype).

norobro
27th April 2012, 22:04
You could try using a delegate. Something like this:
#include <QtGui>

class Delegate : public QStyledItemDelegate
{
QString displayText(const QVariant &value, const QLocale &locale) const{
return QString("item %1").arg(value.toString());
}
};

int main(int argc, char *argv[])
{
QApplication a(argc, argv);
QComboBox comboBox;
comboBox.setEditable(true);
for (int i = 0; i<5; ++i){
comboBox.addItem(QString("%1").arg(i));
}
comboBox.setItemDelegate(new Delegate);
comboBox.show();
return a.exec();
}