QCombobox не использует пользовательский делегат для рендеринга текущего элемента - PullRequest
0 голосов
/ 29 апреля 2019

Я использую пользовательский делегат для визуализации расширенного текста в QComboBox. Он используется для того, чтобы пользователи могли выбрать цвет для отображения переменной на графике. Это работает для элементов в выпадающем меню, но не для выбранного элемента. Любая помощь будет оценена.

Вот код используемого делегата:

class CustomDelegate : public QStyledItemDelegate
{
public:
    CustomDelegate();
protected:
    void paint ( QPainter * painter, const QStyleOptionViewItem & option, const QModelIndex & index ) const;
    QSize sizeHint ( const QStyleOptionViewItem & option, const QModelIndex & index ) const;
};

void CustomDelegate::paint(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index) const{
QStyleOptionViewItemV4 optionV4 = option;
    initStyleOption(&optionV4, index);

    QStyle *style = optionV4.widget? optionV4.widget->style() : QApplication::style();

    QTextDocument doc;
    doc.setHtml(optionV4.text);

    /// Painting item without text
    optionV4.text = QString();
    style->drawControl(QStyle::CE_ItemViewItem, &optionV4, painter);

    QAbstractTextDocumentLayout::PaintContext ctx;

    // Highlighting text if item is selected
    if (optionV4.state & QStyle::State_Selected)
        ctx.palette.setColor(QPalette::Text, optionV4.palette.color(QPalette::Active, QPalette::HighlightedText));

    QRect textRect = style->subElementRect(QStyle::SE_ItemViewItemText, &optionV4);
    painter->save();
    painter->translate(textRect.topLeft());
    painter->setClipRect(textRect.translated(-textRect.topLeft()));
    doc.documentLayout()->draw(painter, ctx);
    painter->restore();
}

QSize CustomDelegate::sizeHint(const QStyleOptionViewItem &option, const QModelIndex &index) const{
QStyleOptionViewItemV4 optionV4 = option;
initStyleOption(&optionV4, index);

QTextDocument doc;
doc.setHtml(optionV4.text);
doc.setTextWidth(optionV4.rect.width());
return QSize(doc.idealWidth(), doc.size().height());
}

Я установил параметры и делегировал для поля со списком, используя подобный код, я удалил некоторые параметры, чтобы уменьшить размер кода:

ui->SelectColor->clear();
    ui->SelectColor->addItem("Select Color");
    ui->SelectColor->addItem("<font color='blue'>Blue</font>");
    ui->SelectColor->addItem("<font color='darkBlue'>Dark Blue</font>");
    ui->SelectColor->addItem("<font color='red'>Red</font>");
    ui->SelectColor->addItem("Dark Yellow");
    ui->SelectColor->addItem("<font color='magenta'>Dark Magenta</font>");
    ui->SelectColor->addItem("White");
    ui->SelectColor->setItemDelegate(new CustomDelegate);

Некоторые из опций - это просто имена, потому что они не очень хорошо выглядят при визуализации.

Image showing combobox rendering drop down but not current

1 Ответ

0 голосов
/ 30 апреля 2019

Ваш пользовательский делегированный элемент элемента применяется к элементам, которые являются частью QComboBox (то есть элементов в всплывающем окне QComboBox ), а не к текущему элементу, который представлен.Самый простой способ достичь желаемого - ввести собственный класс, наследующий QComboBox , а затем переопределить void QWidget :: paintEvent (QPaintEvent * event) , применяя изменения, которые вы хотитеввести, например, установить цветной текст.Другой способ (если по какой-то причине вы не можете ввести другой класс, унаследовавший QComboBox ), - это ввести фильтр событий , который делает что-то сразу после QPaintEvent .Однако использование фильтров событий может быть затруднительным, и я бы посоветовал вам просто ввести какой-то другой класс, а затем переопределить событие рисования.

Теперь, если вы хотите показать текущий элемент так же, какВо всплывающем списке со списком вы можете сделать следующее (код не полный, и вы должны применить его для своих нужд):

virtual void paintEvent(QPaintEvent* e) override
{
    // QComboBox::paintEvent(e); - this will leave just a rectangle in which you can perform your custom drawings.

    // Will make your option colored at least.
    QPainter p(this);

    QTextDocument doc;
    doc.setHtml(this->currentText());
    doc.drawContents(&p, rect());
}

Наконец, стоит отметить, что Рисование QComboBox довольно сложное, и вам, возможно, все равно придется переписать почти все, что Qt уже сделал для вас, так что можно было бы применить другие стили, которые вы можете не потерять.Чтобы сделать это, вы должны взглянуть на исходный код этого класса.Вы можете сделать это в Code Browser от Woboq для C & C ++ (QComboBox) .Надеюсь, это прояснит проблему для вас больше, и теперь вы знаете, что делать, чтобы достичь своей цели.

...