Может ли 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 );
}