2016-12-28 19 views
1

Итак, у меня есть QComboBox.QComboBox предоставил текст по выбранному элементу

enter image description here

Если currentText() слишком длинный для виджета, то я хочу, чтобы показать многоточие.

Как это:

enter image description here

Итак:

void MyComboBox::paintEvent(QPaintEvent *) 
{ 
     QStylePainter painter(this); 
     QStyleOptionComboBox opt; 
     initStyleOption(&opt); 
     painter.drawComplexControl(QStyle::CC_ComboBox, opt); 

     QRect rect = this->rect(); 
     //this is not ideal 
     rect.setLeft(rect.left() + 7); 
     rect.setRight(rect.width() - 15); 
     // 

     QTextOption option; 
     option.setAlignment(Qt::AlignVCenter); 

     QFontMetrics fontMetric(painter.font()); 
     const QString elidedText = QAbstractItemDelegate::elidedText(fontMetric, rect.width(), Qt::ElideRight, this->currentText()); 
     painter.drawText(rect, elidedText, option); 
} 

Это работает flawlessy. Проблема заключается в коде между комментариями, потому что я жестко кодирую расстояния от левой и правой границы. Это заставляет меня съеживаться.

Результат без этого кода:

enter image description here

Кто-нибудь знает более общий способ сделать это, без жесткого кодирования? Спасибо

ответ

1

Где текст должен быть нарисован, в точности зависит от используемого стиля. Вы можете получить информацию о (некоторых) позициях подэлементов с помощью QStyle::subControlRect. Subcontrol, который соответствует тексту combo box лучше всего, выглядит QStyle::SC_ComboBoxEditField, хотя, если у элемента есть значок, это нужно также учитывать. Если у предметов нет значков, вы можете пойти с

QRect textRect = style()->subControlRect(QStyle::CC_ComboBox, &opt, QStyle::SC_ComboBoxEditField, this); 
    QFontMetrics fontMetric(painter.font()); 
    const QString elidedText = QAbstractItemDelegate::elidedText(fontMetric, textRect.width(), Qt::ElideRight, this->currentText()); 
    opt.currentText = elidedText; 
    painter.drawControl(QStyle::CE_ComboBoxLabel, opt); 

Возможно, вы захотите посмотреть, как, например, QFusionStyle::drawControl работает для деталей.

В общем, если вы хотите, чтобы все ваши поля со списком отображали текст, вы должны рассмотреть возможность внедрения своего собственного QProxyStyle и только переопределить MyStyle::drawControl для QStyle::CE_ComboBoxLabel.

+0

благодарим за предложение .. как только у меня есть время, я попытаюсь исследовать то, что вы предложили! –

+0

Он работает безупречно! Спасибо! –