【问题标题】:QCombobox not using custom delegate to render current itemQCombobox 不使用自定义委托来呈现当前项目
【发布时间】:2019-04-29 17:22:36
【问题描述】:

我正在使用自定义委托在 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);

有些选项只是名称,因为它们在渲染时看起来不太好。

【问题讨论】:

    标签: qt qcombobox


    【解决方案1】:

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

    现在,如果您想以与组合框列表弹出窗口中的选项相同的方式显示当前项目,您可以执行以下操作(代码不完整,您应该自己应用它):

    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) 中执行此操作。希望这可以为您更清楚地阐明问题,现在您知道该做什么来实现您的目标。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-10-20
      相关资源
      最近更新 更多