Может ли QComboBox отображать значение, отличное от того, что указано в его списке?

Используя Qt 5.9 в Linux, у меня есть QComboBox с несколькими метками.

qc = new QComboBox;
qc->addItem(tr("Red"));
qc->addItem(tr("Green"));
qc->addItem(tr("Blue"));

Допустим, пользователь активирует QComboBox, и в раскрывающемся списке отображаются 3 цветные метки. Затем пользователь выбирает 1-й элемент (красный).

Я хочу, чтобы QComboBox отображал значение, отличное от выбранного. То есть, если выбран красный, то отображается число, возможно, 1 для первого элемента (или это может быть R для красного), а если выбран зеленый, то отображается 2 (или G) для второго элемента.

Моя цель в этом состоит в том, чтобы использовать меньше места на экране (меньше ширины), чем на самом деле необходимо, чтобы показать полный текст выбора, потому что некоторые из моих строк элементов довольно длинные, и желательна намного более короткая метка, когда QComboBox не активирован в это выпадающее состояние. Кроме того, строки элементов являются описательными, и аббревиатуры будут лучше отображаться.

Редактировать:
Используя пример Марека, подумал, что это может помочь. Вот что у меня есть. Я ожидаю, что если пользователь выбирает из списка, то после него должны отображаться буквы R, G или B.

QStandardItem *red = new QStandardItem();
red->setData(tr("Red"), Qt::DisplayRole);
red->setData("R", Qt::UserRole);

QStandardItem *green = new QStandardItem();
green->setData(tr("Green"), Qt::DisplayRole);
green->setData("G", Qt::UserRole);

QStandardItem *blue = new QStandardItem();
blue->setData(tr("Blue"), Qt::DisplayRole);
blue->setData("B", Qt::UserRole);

QStandardItemModel *rgb_model = new QStandardItemModel(this);
rgb_model->setItem(0, red);
rgb_model->setItem(1, green);
rgb_model->setItem(2, blue);

QComboBox *rgb_cb = new QComboBox();
rgb_cb->setModel(rgb_model);

У меня такое ощущение, что это потому, что я не совсем понимаю, как использовать Qt::UserRole.

2 ответа

Решение

Да, это возможно. QComboBox использует модель данных для управления элементами. Вы должны предоставить собственную модель данных с элементами с соответствующими значениями данных.

QStandardItem *itme1 = new QStandardItem();
item1->setData(tr("Red"), Qt::DisplayRole);
item1->setData("1", Qt::UserRole); // note doesn't have to be a string.

QStandardItem *itme2 = new QStandardItem();
item2->setData(tr("Green"), Qt::DisplayRole);
item2->setData("2", Qt::UserRole);

QStandardItemModel *model = new QStandardItemModel(this);
mode->setItem(1, item1);
mode->setItem(2, item2);

qc->setModel(model);

Это должно работать, но я не проверял это. По крайней мере, это должно быть какой-то подсказкой.

Пожалуйста, просмотрите документацию QComboBox, особенно о ролях.


Другое решение - использовать переводы различной длины. Вы можете предоставить перевод пары для одной строки. Каждый перевод должен быть графически короче, чем предыдущий.

В такой ситуации QString содержит все возможности, разделенные пространственным характером. Когда такая строка отображается, будет использоваться первая подстрока (между разделителями), которая будет занимать доступное пространство.

Теперь я не помню, что такое значение разделителя. Я использовал это очень давно (с Qt 4.8) и теперь не могу найти ссылку на него.

В вашем примере для краткости просто сделайте:

qc->setWidth( 20 );

Но если вы действительно хотите, чтобы пользователь что-то выбрал, то:

connect (qc, SIGNAL (onCurrentIndexChanged (int)), SLOT (changeComboText ())); [...]

void changeComboText()
{
   QString shortText;
  //Determine short value for shortText
   qc->setCurrentText( shortText );
}
Другие вопросы по тегам