QT风格(QStyle):绘制一个自定义QComboBox

绘制QComboBox即把QComboBoxd组成元素绘制出来。

元素如下:

这三个都是子控件,可交互的,图标元素默认是PE_IndicatorArrowDown,一个下箭头。

绘制设计图:

过程实在没啥好说的,绘制套路和前面都一样,无非是确定好子控件/子元素位置,然后在相应位置绘制需要绘制的内容。

完整代码:

.h文件:

#ifndef MYCOMBOBOXSTYLE_H
#define MYCOMBOBOXSTYLE_H

#include <QProxyStyle>

class myComboBoxStyle : public QProxyStyle
{
public:
    myComboBoxStyle();
    void drawComplexControl(ComplexControl which,const QStyleOptionComplex *option,QPainter *painter,const QWidget *widget = nullptr) const override;
    QRect subControlRect(ComplexControl whichControl,const QStyleOptionComplex *option,SubControl whichSubControl,const QWidget *widget = nullptr) const override;
    void drawPrimitive(PrimitiveElement element, const QStyleOption *option, QPainter *painter, const QWidget *widget = nullptr) const override;
};

#endif // MYCOMBOBOXSTYLE_H

 .cpp文件:

#include "mycomboboxstyle.h"
#include <QPainter>
#include <QStyleOptionComplex>
#include <QDebug>

myComboBoxStyle::myComboBoxStyle()
{

}
void myComboBoxStyle::drawComplexControl(ComplexControl which,const QStyleOptionComplex *option,QPainter *painter,const QWidget *widget) const
{
    if (which == CC_ComboBox)
    {
        if(const QStyleOptionComboBox * cbOption = qstyleoption_cast<const QStyleOptionComboBox *>(option))
        {
            painter->save();
            QRect rect = subControlRect(CC_ComboBox, option,SC_ComboBoxFrame).adjusted(+1, +1, -1, -1);
            painter->setBrush(QColor("#128bf1"));
            painter->drawRect(rect);

            rect = subControlRect(CC_ComboBox, option,SC_ComboBoxEditField).adjusted(+2, +2, -2, -2);
            QLinearGradient gradient(rect.topLeft(),rect.bottomRight());
            gradient.setColorAt(0.0, QColor("#fa709a"));
            gradient.setColorAt(1.0, QColor("#fee140"));
            painter->setPen(Qt::NoPen);
            painter->setBrush(gradient);
            painter->drawRect(rect);

            rect = subControlRect(CC_ComboBox, option,SC_ComboBoxArrow).adjusted(+1, +1, -1, -1);
            painter->setPen(Qt::transparent);
            painter->translate(option->rect.x(),option->rect.y());
            QLinearGradient gradient2(rect.topLeft(),rect.bottomRight());
            gradient2.setColorAt(0.0, QColor("#84fab0"));
            gradient2.setColorAt(1.0, QColor("#8fd3f4"));
            painter->setBrush(gradient2);
            painter->drawRect(rect);
            painter->restore();

            QStyleOption arrowOpt(*cbOption);
            arrowOpt.rect = rect.adjusted(+rect.width() * 0.3, +rect.height() * 0.3,
                                          -rect.width() * 0.3, -rect.height() * 0.3);
            drawPrimitive(PE_IndicatorArrowDown, &arrowOpt, painter);

            if(option->activeSubControls == SC_ComboBoxEditField ||
               option->activeSubControls == SC_ComboBoxArrow)
            {
                painter->save();
                QColor slightlyOpaqueBlack(0, 0, 0, 63);
                painter->setBrush(slightlyOpaqueBlack);
                painter->drawRect(widget->rect());
                painter->restore();
            }
        }
    }
    else
    {
        return QProxyStyle::drawComplexControl(which, option, painter,widget);
    }
}

void myComboBoxStyle::drawPrimitive(PrimitiveElement which, const QStyleOption *option, QPainter *painter, const QWidget *widget) const
{
    switch (which)
    {
        case PE_IndicatorArrowDown:
        {
            painter->save();
            painter->translate(option->rect.x(),option->rect.y());
            QPainterPath drawtriangle;  //画三角形
            drawtriangle.moveTo(0,0);
            drawtriangle.lineTo(option->rect.width()/2,option->rect.height());
            drawtriangle.lineTo(option->rect.width(),0);
            drawtriangle.lineTo(0,0);
            painter->setPen(QPen(QColor("#128bf1"), 2));
            painter->drawPath(drawtriangle);  //绘制出图形
            painter->restore();
        }
        break;
        default:
            QProxyStyle::drawPrimitive(which, option, painter, widget);
    }
}

QRect myComboBoxStyle::subControlRect(ComplexControl whichControl,const QStyleOptionComplex *option,SubControl whichSubControl,const QWidget *widget) const
{
    if (whichControl == CC_ComboBox)
    {
        switch (whichSubControl)
        {
            case SC_ComboBoxEditField:
                return QRect(0,0,option->rect.width() * 0.7,option->rect.height()).adjusted(+2, +2, -2, -2);
            case SC_ComboBoxFrame:
                return QRect(0,0,option->rect.width() * 0.7,option->rect.height());
            case SC_ComboBoxArrow:
                return QRect(option->rect.width() * 0.7, 0, option->rect.width() * 0.3, option->rect.height());
            default:
                return QProxyStyle::subControlRect(whichControl, option,whichSubControl, widget);
        }
    }
    else
    {
        return QProxyStyle::subControlRect(whichControl, option,whichSubControl, widget);
    }
}

效果:

 

 

可参考:Qt中QComboBox下拉列表(popup)位置与样式的控制

评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值