QCombobox不使用自定义委托来呈现当前项目

时间:2019-04-29 17:22:36

标签: qt qcombobox

我正在使用自定义委托在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 :(得分:0)

您的自定义样式的项目委托将应用于QComboBox中一部分的项目(即QComboBox弹出窗口中的项目),而不应用于所表示的当前项目。实现所需目标的最简单方法是引入继承QComboBox的自定义类,然后通过应用要引入的更改来覆盖void QWidget::paintEvent(QPaintEvent *event)方法,例如设置一些彩色文本。另一种方法(以防万一由于某种原因而不能引入另一个继承QComboBox的类)是引入event filter,该类在QPaintEvent之后执行某些操作。但是,使用事件过滤器可能会比较棘手,我建议您先引入另一个类,然后覆盖paint事件。

现在,如果要以与组合框列表弹出窗口中的选项相同的方式显示当前项目,则可以执行以下操作(代码不完整,您应该自己将其应用于需要的内容):< / p>

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 by Woboq for C & C++ (QComboBox)中进行此操作。希望这可以为您进一步解决问题,现在您知道该怎么做才能实现目标。