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

参考《c++ qt4编程(第二版)》19.2章节

一个QSpinBox的组成部分如下:


使用QStyle绘制默认的QSpinBox就会绘制这些元素:



这就是QStyle绘制的默认QSpinBox。

要绘制一个自定义的QSpinBox只需要在自定义的风格里面绘制这几个元素就行了。

从drawComplexControl函数开始绘制:



这里drawBronzeSpinBoxButton()函数用来绘制上下按钮,



即这两个

void BronzeStyle::drawBronzeSpinBoxButton(SubControl which, const QStyleOptionComplex *option,
QPainter *painter) const
{
PrimitiveElement arrow = PE_IndicatorArrowLeft;//向左的箭头
QRect buttonRect = option->rect;
if ((which == SC_SpinBoxUp) && (option->direction != Qt::RightToLeft))
{
arrow = PE_IndicatorArrowRight;//向右的箭头
buttonRect.translate(buttonRect.width() / 2, 0);//translate矩形移到指定位置,这里意思是移到option->rect的中间位置
}
buttonRect.setWidth((buttonRect.width() + 1) / 2);//矩形宽度减半

QStyleOption buttonOpt(*option);

painter->save();
painter->setClipRect(buttonRect/*, Qt::IntersectClip*/);
//setClipRect函数主要用来设置裁剪区域。区域外绘图都是无效的。只在buttonRect范围内绘制

if (option->activeSubControls != which)//不是当前活动的子控件
{
buttonOpt.state &= ~(State_MouseOver/*在鼠标下面*/ | State_On/*按下*/ | State_Sunken/*凹陷*/);
}
drawBronzeBevel(&buttonOpt, painter);
//至此背景绘制完成

QStyleOption arrowOpt(buttonOpt);
arrowOpt.rect = subControlRect(CC_SpinBox, option, which).adjusted(+3, +3, -3, -3);
arrow = PE_IndicatorSpinUp;//测试
if (arrowOpt.rect.isValid())
{
drawPrimitive(arrow, &arrowOpt, painter);
}

painter->restore();
}

void BronzeStyle::drawBronzeBevel(const QStyleOption *option, QPainter *painter) const
{
QColor buttonColor = option->palette.button().color();
int coeff = (option->state & State_MouseOver) ? 115 : 105;

QLinearGradient gradient(0, 0, 0, option->rect.height());
gradient.setColorAt(0.0, option->palette.light().color());
gradient.setColorAt(0.2, buttonColor.lighter(coeff));
gradient.setColorAt(0.8, buttonColor.darker(coeff));
gradient.setColorAt(1.0, option->palette.dark().color());

double penWidth = 1.0;
if (const QStyleOptionButton *buttonOpt = qstyleoption_cast(option))
{
if (buttonOpt->features & QStyleOptionButton::DefaultButton)
penWidth = 2.0;
}

QRect roundRect = option->rect.adjusted(+1, +1, -1, -1);
if (!roundRect.isValid())
return;

int diameter = 12;
int cx = 100 * diameter / roundRect.width();
int cy = 100 * diameter / roundRect.height();

painter->save();
painter->setPen(Qt::NoPen);
painter->setBrush(gradient);
painter->drawRoundRect(roundRect, cx, cy);//绘制圆角矩形

if (option->state & (State_On | State_Sunken))//按下时,绘制一层暗色
{
QColor slightlyOpaqueBlack(0, 0, 0, 63);
painter->setBrush(slightlyOpaqueBlack);
painter->drawRoundRect(roundRect, cx, cy);//绘制圆角矩形
}

painter->setRenderHint(QPainter::Antialiasing, true);
painter->setPen(QPen(option->palette.foreground(), penWidth));
painter->setBrush(Qt::NoBrush);
painter->drawRoundRect(roundRect, cx, cy);
painter->restore();
}

函数传入了整个QSpinBox的QStyleOptionComplex

绘制上按钮SC_SpinBoxUp的过程如下:

其中PrimitiveElement是原始元素,这里设置成向左和向右的箭头,也可以设置成别的,调用重载函数drawPrimitive()进行绘制,可以在该函数里自由绘制,如PE_IndicatorSpinUp默认绘制是一个上三角



你可以在这里自由指定当绘制PE_IndicatorSpinUp元素时绘制文字



然后是绘制文本框SC_SpinBoxEditField

重写函数subControlRect里面定义了子控件的绘制范围


QRect rect = subControlRect(CC_SpinBox, option,SC_SpinBoxEditField).adjusted(-1, 0, +1, 0);
painter->save();
// painter->setPen(QPen(option->palette.mid(), 1.0));
painter->setPen(QPen(Qt::red,5));
painter->drawLine(rect.topLeft(), rect.bottomLeft());
painter->drawLine(rect.topRight(), rect.bottomRight());
painter->restore();

效果:



总的来说使用qstyle绘制自定义的控件是非常繁琐的,一般不建议使用。

免费学习C++ Qt开发教程视频,点击下面链接免费报名领取视频学习资料

C/C++项目实战/Qt5/C语言/c++/数据库/OpenCV/MFC/QT项目-学习视频教程-腾讯课堂


按上一篇绘制自定义QSpinBox的过程,再来绘制一个QSpinBox。

设计图:



把按钮放上面

在这之前先看一下成品:

上一篇说了,绘制自定义QSpinBox实际上就是给QSpinBox中的这些原始组成元素指定好位置并绘制出来。



设计这些元素的尺寸如下:



即确定子控件位置的subControlRect()函数:

QRect mySpinboxStyle::subControlRect(ComplexControl whichControl,const QStyleOptionComplex *option,SubControl whichSubControl,const QWidget *widget) const
{
if (whichControl == CC_SpinBox)
{
switch (whichSubControl)
{
case SC_SpinBoxFrame:
return option->rect;
case SC_SpinBoxEditField:
return QRect(option->rect.x(), option->rect.height() * 0.4 , option->rect.width(), option->rect.height() * 0.6).adjusted(+10, +10, -10, -10);
case SC_SpinBoxDown:
return QRect(option->rect.width()/2,0,option->rect.width()/2,option->rect.height()*0.4);
case SC_SpinBoxUp:
return QRect(0,0,option->rect.width()/2,option->rect.height()*0.4);
default:
return QRect();
}
}
else
{
return QProxyStyle::subControlRect(whichControl, option,whichSubControl, widget);
}
}

然后开始绘制:

绘制从drawComplexControl()函数开始,首先绘制上下按钮



void mySpinboxStyle::drawBronzeSpinBoxButton(SubControl which, const QStyleOptionComplex *option,QPainter *painter,const QWidget * widget) const
{
PrimitiveElement element;
QRect buttonRect = option->rect;

if (which == SC_SpinBoxUp)//上按钮
{
buttonRect.translate(0, 0);//translate矩形移到指定位置
element = PE_IndicatorSpinPlus;
}
else if(which == SC_SpinBoxDown)
{
buttonRect.translate(buttonRect.width() / 2, 0);
element = PE_IndicatorSpinMinus;
}
buttonRect.setWidth(buttonRect.width() / 2);
buttonRect.setHeight(buttonRect.width() * 0.4);
QStyleOption buttonOpt(*option);
buttonOpt.rect = buttonRect;

//绘制背景开始
painter->save();
painter->setClipRect(buttonRect);//在此范围内绘制背景
if (option->activeSubControls != which)//不是当前活动的子控件
{
buttonOpt.state &= ~(State_MouseOver/*在鼠标下面*/ | State_On/*按下*/ | State_Sunken/*凹陷*/);
}
QLinearGradient gradient(0, 0, 0, buttonOpt.rect.height());//y轴使用渐变
gradient.setColorAt(0.0, QColor("#5ee7df"));
gradient.setColorAt(1.0, QColor("#b490ca"));
painter->setPen(Qt::NoPen);
painter->setBrush(gradient);
QRect roundRect = buttonOpt.rect.adjusted(+1, +1, -1, -1);
int diameter = 12;
int cx = 100 * diameter / buttonOpt.rect.width();
int cy = 100 * diameter / buttonOpt.rect.height();

painter->drawRoundRect(roundRect, cx, cy);//绘制圆角矩形
if (buttonOpt.state & (State_On | State_Sunken))//按下时,绘制一层暗色
{
QColor slightlyOpaqueBlack(0, 0, 0, 63);
painter->setBrush(slightlyOpaqueBlack);
painter->drawRoundRect(roundRect, cx, cy);//绘制圆角矩形
}
//绘制背景结束
painter->restore();

//绘制图标
QStyleOption arrowOpt(buttonOpt);
QRect subRect = subControlRect(CC_SpinBox, option, which);
arrowOpt.rect = subRect.adjusted(+subRect.width() * 0.3, +subRect.height() * 0.3,
-subRect.width() * 0.3, -subRect.height() * 0.3);
drawPrimitive(element, &arrowOpt, painter);
}

这个函数用来绘制上下按钮的背景和按钮上面的图标

背景使用了线性渐变,如果没有好的渐变配色方案可以参考这里:收藏 | 四个免费的渐变配色网站!

这里绘制的时候使用了adjusted(+1, +1, -1, -1),即给四周留下了一点空间显得不拥挤。绘制完上下按钮的背景时的效果:



然后是绘制按钮的图标,

QRect subRect = subControlRect(CC_SpinBox, option, which);
arrowOpt.rect = subRect.adjusted(+subRect.width() * 0.3, +subRect.height() * 0.3,
-subRect.width() * 0.3, -subRect.height() * 0.3);

这里从subControlRect()获取上下按钮的范围之后再次压缩了范围



在此范围内绘制图标

这里设置了上下按钮分别使用PE_IndicatorSpinPlus / PE_IndicatorSpinMinus,默认是代表加减号的意思。

如果使用默认设置,在drawPrimitive()中直接调用 QProxyStyle::drawPrimitive(which, option, painter, widget);效果:



不太好看,我们按设计图给它画上三角形。

void mySpinboxStyle::drawPrimitive(PrimitiveElement which, const QStyleOption *option, QPainter *painter, const QWidget *widget) const
{
switch (which)
{
case PE_IndicatorSpinPlus:
{
painter->save();
painter->translate(option->rect.x(),option->rect.y());
QPainterPath drawtriangle; //画三角形
drawtriangle.moveTo(0, option->rect.height());//左下角
drawtriangle.lineTo(option->rect.width()/2, 0);//第二点坐标为(width/2,width/2)
drawtriangle.lineTo(option->rect.width(), option->rect.height());//右下角,第三坐标(width, height),移动到右下角结束点,整体形成一个闭合路径
drawtriangle.lineTo(0, option->rect.height());
painter->setPen(QPen(QColor("#128bf1"), 2));
painter->drawPath(drawtriangle); //绘制出图形
painter->restore();
}
break;
case PE_IndicatorSpinMinus:
{
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);
}
}



这里注意:

painter指针是绘制一开始起从drawComplexControl()函数传过来的,每次绘制前设置painter->save();保存设置绘制完成painter->restore();恢复设置,到drawPrimitive()绘制的原点还是在上下按钮的(0,0)点,设置painter->translate(option->rect.x(),option->rect.y());是将绘制的原点设为绘制图标的原点,就比较方便



下一步是给SC_SpinBoxEditField加上边框:



QRect rect = subControlRect(CC_SpinBox, option,SC_SpinBoxEditField).adjusted(-10, -10, +10, +10);
painter->save();
QLinearGradient gradient(0, 0, rect.width(), rect.height());//x轴使用渐变
gradient.setColorAt(0.0, QColor("#fa709a"));
gradient.setColorAt(1.0, QColor("#fee140"));
painter->setPen(Qt::NoPen);
painter->setBrush(gradient);
QRect roundRect = rect.adjusted(+1, +1, -1, -1);
int diameter = 12;
int cx = 100 * diameter / rect.width();
int cy = 100 * diameter / rect.height();
painter->drawRoundRect(roundRect, cx, cy);//绘制圆角矩形
painter->restore();

此时的效果:


到这基本完成,然而编辑框里的数字太小了,这里可以设置它的字体并设置文本居中:

ui->spinBox->setAlignment(Qt::AlignCenter);
QFont f;
f.setPixelSize(24);
ui->spinBox->setFont(f);

最终效果:

样式完整代码:

.h文件:

#ifndef MYSPINBOXSTYLE_H
#define MYSPINBOXSTYLE_H

#include 

class mySpinboxStyle : public QProxyStyle
{

public:

mySpinboxStyle();
void drawComplexControl(ComplexControl which,const QStyleOptionComplex *option,QPainter *painter,const QWidget *widget = nullptr) const override;
void drawBronzeSpinBoxButton(SubControl which, const QStyleOptionComplex *option, QPainter *painter, const QWidget *widget) const;
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 // MYSPINBOXSTYLE_H

.cpp文件:

#include "myspinboxstyle.h"
#include 
#include 
#include 

mySpinboxStyle::mySpinboxStyle()
{

}

QRect mySpinboxStyle::subControlRect(ComplexControl whichControl,const QStyleOptionComplex *option,SubControl whichSubControl,const QWidget *widget) const
{
if (whichControl == CC_SpinBox)
{
switch (whichSubControl)
{
case SC_SpinBoxFrame:
return option->rect;
case SC_SpinBoxEditField:
return QRect(option->rect.x(), option->rect.height() * 0.4 , option->rect.width(), option->rect.height() * 0.6).adjusted(+10, +10, -10, -10);
case SC_SpinBoxDown:
return QRect(option->rect.width()/2,0,option->rect.width()/2,option->rect.height()*0.4);
case SC_SpinBoxUp:
return QRect(0,0,option->rect.width()/2,option->rect.height()*0.4);
default:
return QRect();
}
}
else
{
return QProxyStyle::subControlRect(whichControl, option,whichSubControl, widget);
}
}

void mySpinboxStyle::drawComplexControl(ComplexControl which,const QStyleOptionComplex *option,QPainter *painter,const QWidget *widget) const
{
if (which == CC_SpinBox)
{
drawBronzeSpinBoxButton(SC_SpinBoxDown, option, painter,widget);
drawBronzeSpinBoxButton(SC_SpinBoxUp, option, painter,widget);

QRect rect = subControlRect(CC_SpinBox, option,SC_SpinBoxEditField).adjusted(-10, -10, +10, +10);
painter->save();
QLinearGradient gradient(0, 0, rect.width(), rect.height());//x轴使用渐变
gradient.setColorAt(0.0, QColor("#fa709a"));
gradient.setColorAt(1.0, QColor("#fee140"));
painter->setPen(Qt::NoPen);
painter->setBrush(gradient);
QRect roundRect = rect.adjusted(+1, +1, -1, -1);
int diameter = 12;
int cx = 100 * diameter / rect.width();
int cy = 100 * diameter / rect.height();
painter->drawRoundRect(roundRect, cx, cy);//绘制圆角矩形
painter->restore();
}
else
{
return QProxyStyle::drawComplexControl(which, option, painter,widget);
}
}

void mySpinboxStyle::drawBronzeSpinBoxButton(SubControl which, const QStyleOptionComplex *option,QPainter *painter,const QWidget * widget) const
{
PrimitiveElement element;
QRect buttonRect = option->rect;

if (which == SC_SpinBoxUp)//上按钮
{
buttonRect.translate(0, 0);//translate矩形移到指定位置
element = PE_IndicatorSpinPlus;//PE_IndicatorSpinPlus
}
else if(which == SC_SpinBoxDown)
{
buttonRect.translate(buttonRect.width() / 2, 0);
element = PE_IndicatorSpinMinus;
}
buttonRect.setWidth(buttonRect.width() / 2);
buttonRect.setHeight(buttonRect.width() * 0.4);
QStyleOption buttonOpt(*option);
buttonOpt.rect = buttonRect;

//绘制背景开始
painter->save();
painter->setClipRect(buttonRect);//在此范围内绘制背景
if (option->activeSubControls != which)//不是当前活动的子控件
{
buttonOpt.state &= ~(State_MouseOver/*在鼠标下面*/ | State_On/*按下*/ | State_Sunken/*凹陷*/);
}
QLinearGradient gradient(0, 0, 0, buttonOpt.rect.height());//y轴使用渐变
gradient.setColorAt(0.0, QColor("#5ee7df"));
gradient.setColorAt(1.0, QColor("#b490ca"));
painter->setPen(Qt::NoPen);
painter->setBrush(gradient);
QRect roundRect = buttonOpt.rect.adjusted(+1, +1, -1, -1);
int diameter = 12;
int cx = 100 * diameter / buttonOpt.rect.width();
int cy = 100 * diameter / buttonOpt.rect.height();

painter->drawRoundRect(roundRect, cx, cy);//绘制圆角矩形
if (buttonOpt.state & (State_On | State_Sunken))//按下时,绘制一层暗色
{
QColor slightlyOpaqueBlack(0, 0, 0, 63);
painter->setBrush(slightlyOpaqueBlack);
painter->drawRoundRect(roundRect, cx, cy);//绘制圆角矩形
}
//绘制背景结束
painter->restore();

//绘制图标
QStyleOption arrowOpt(buttonOpt);
QRect subRect = subControlRect(CC_SpinBox, option, which);
arrowOpt.rect = subRect.adjusted(+subRect.width() * 0.3, +subRect.height() * 0.3,
-subRect.width() * 0.3, -subRect.height() * 0.3);
drawPrimitive(element, &arrowOpt, painter);
}

void mySpinboxStyle::drawPrimitive(PrimitiveElement which, const QStyleOption *option, QPainter *painter, const QWidget *widget) const
{
switch (which)
{
case PE_IndicatorSpinPlus:
{
painter->save();
painter->translate(option->rect.x(),option->rect.y());
QPainterPath drawtriangle; //画三角形
drawtriangle.moveTo(0, option->rect.height());//左下角
drawtriangle.lineTo(option->rect.width()/2, 0);//第二点坐标为(width/2,width/2)
drawtriangle.lineTo(option->rect.width(), option->rect.height());//右下角,第三坐标(width, height),移动到右下角结束点,整体形成一个闭合路径
drawtriangle.lineTo(0, option->rect.height());
painter->setPen(QPen(QColor("#128bf1"), 2));
painter->drawPath(drawtriangle); //绘制出图形
painter->restore();
}
break;
case PE_IndicatorSpinMinus:
{
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);
}
}

按照之前的方法再来绘制两个QSpinBox。

设计图:



根据这个设计图改写子控件位置:

QRect mySpinboxStyle::subControlRect(ComplexControl whichControl,const QStyleOptionComplex *option,SubControl whichSubControl,const QWidget *widget) const
{
if (whichControl == CC_SpinBox)
{
switch (whichSubControl)
{
case SC_SpinBoxFrame:
return option->rect;
case SC_SpinBoxEditField:
return QRect(0, option->rect.height() * 0.3 , option->rect.width(), option->rect.height() * 0.4).adjusted(+10, +10, -10, -10);
case SC_SpinBoxDown:
return QRect(0,option->rect.height() * 0.7,option->rect.width(),option->rect.height()*0.3);
case SC_SpinBoxUp:
return QRect(0,0,option->rect.width(),option->rect.height()*0.3);
default:
return QRect();
}
}
else
{
return QProxyStyle::subControlRect(whichControl, option,whichSubControl, widget);
}
}

绘制背景和图标:

void mySpinboxStyle::drawBronzeSpinBoxButton(SubControl which, const QStyleOptionComplex *option,QPainter *painter,const QWidget * widget) const
{
PrimitiveElement element;
QRect buttonRect = option->rect;

if (which == SC_SpinBoxUp)//上按钮
{
buttonRect.translate(0, 0);//translate矩形移到指定位置
element = PE_IndicatorSpinPlus;//PE_IndicatorSpinPlus
}
else if(which == SC_SpinBoxDown)
{
buttonRect.translate(0, buttonRect.height() * 0.7);
element = PE_IndicatorSpinMinus;
}
buttonRect.setHeight(buttonRect.height() * 0.3);
QStyleOption buttonOpt(*option);
buttonOpt.rect = buttonRect;

//绘制背景开始
painter->save();
painter->setClipRect(buttonRect);//在此范围内绘制背景
if (option->activeSubControls != which)//不是当前活动的子控件
{
buttonOpt.state &= ~(State_MouseOver/*在鼠标下面*/ | State_On/*按下*/ | State_Sunken/*凹陷*/);
}
QLinearGradient gradient(buttonOpt.rect.topLeft(),buttonOpt.rect.bottomRight());
gradient.setColorAt(0.0, QColor("#5ee7df"));
gradient.setColorAt(1.0, QColor("#b490ca"));
painter->setBrush(gradient);

QRect roundRect = buttonOpt.rect.adjusted(+1, +1, -1, -1);
int diameter = 12;
int cx = 100 * diameter / buttonOpt.rect.width();
int cy = 100 * diameter / buttonOpt.rect.height();

painter->drawRoundRect(roundRect, cx, cy);//绘制圆角矩形
if (buttonOpt.state & (State_On | State_Sunken))//按下时,绘制一层暗色
{
QColor slightlyOpaqueBlack(0, 0, 0, 63);
painter->setBrush(slightlyOpaqueBlack);
painter->drawRoundRect(roundRect, cx, cy);//绘制圆角矩形
}
//绘制背景结束
painter->restore();

//绘制图标
QStyleOption arrowOpt(buttonOpt);
QRect subRect = subControlRect(CC_SpinBox, option, which);
arrowOpt.rect = subRect.adjusted(+subRect.width() * 0.3, +subRect.height() * 0.3,
-subRect.width() * 0.3, -subRect.height() * 0.3);
drawPrimitive(element, &arrowOpt, painter);
}


其他的都和上一篇一样。

效果:

再来画最后一个,



和前面的整体区别不大就是椭圆形的

其他的地方不需要改,只需要改这里,绘制上下键背景的时候由绘制圆角矩形改成绘制弧形:

void mySpinboxStyle::drawBronzeSpinBoxButton(SubControl which, const QStyleOptionComplex *option,QPainter *painter,const QWidget * widget) const
{
PrimitiveElement element;
QRect buttonRect = option->rect;

if (which == SC_SpinBoxUp)//上按钮
{
buttonRect.translate(0, 0);//translate矩形移到指定位置
element = PE_IndicatorSpinPlus;//PE_IndicatorSpinPlus
}
else if(which == SC_SpinBoxDown)
{
buttonRect.translate(0, buttonRect.height() * 0.7);
element = PE_IndicatorSpinMinus;
}
buttonRect.setHeight(buttonRect.height() * 0.3);
QStyleOption buttonOpt(*option);
buttonOpt.rect = buttonRect;

//绘制背景开始
painter->save();
painter->setRenderHint(QPainter::Antialiasing, true);
painter->setClipRect(buttonRect);//在此范围内绘制背景
if (option->activeSubControls != which)//不是当前活动的子控件
{
buttonOpt.state &= ~(State_MouseOver/*在鼠标下面*/ | State_On/*按下*/ | State_Sunken/*凹陷*/);
}
QLinearGradient gradient(buttonOpt.rect.topLeft(),buttonOpt.rect.bottomRight());
gradient.setColorAt(0.0, QColor("#5ee7df"));
gradient.setColorAt(1.0, QColor("#b490ca"));
painter->setBrush(gradient);
painter->setPen(Qt::NoPen);

QRect roundRect = buttonOpt.rect.adjusted(+1, +1, -1, -1);
int startAngle = 0 * 16;//起始角度,角度可以为负值,如-30*16
int spanAngle = 180 * 16;//覆盖的角度,绘制方向为逆时针方向
roundRect.setHeight(roundRect.height() * 2);

if(which == SC_SpinBoxDown)
{
startAngle = 180 * 16;
spanAngle = 180 * 16;
roundRect.moveTo(0,option->rect.height()*0.4);
}

painter->drawPie(roundRect, startAngle, spanAngle);
if (buttonOpt.state & (State_On | State_Sunken))//按下时,绘制一层暗色
{
QColor slightlyOpaqueBlack(0, 0, 0, 63);
painter->setBrush(slightlyOpaqueBlack);
painter->drawPie(roundRect, startAngle, spanAngle);
}
//绘制背景结束
painter->restore();

//绘制图标
QStyleOption arrowOpt(buttonOpt);
QRect subRect = subControlRect(CC_SpinBox, option, which);
arrowOpt.rect = subRect.adjusted(+subRect.width() * 0.3, +subRect.height() * 0.3,
-subRect.width() * 0.3, -subRect.height() * 0.3);
drawPrimitive(element, &arrowOpt, painter);
}

效果:


免费学习C++ Qt开发教程视频,点击下面链接免费报名领取视频学习资料

C/C++项目实战/Qt5/C语言/c++/数据库/OpenCV/MFC/QT项目-学习视频教程-腾讯课堂


原文链接:https://blog.csdn.net/kenfan1647/article/details/110680037

展开阅读全文

页面更新:2024-02-08

标签:角形   范围内   矩形   控件   图标   函数   按钮   背景   风格   位置   效果

1 2 3 4 5

上滑加载更多 ↓
推荐阅读:
友情链接:
更多:

本站资料均由网友自行发布提供,仅用于学习交流。如有版权问题,请与我联系,QQ:4156828  

© CopyRight 2008-2024 All Rights Reserved. Powered By bs178.com 闽ICP备11008920号-3
闽公网安备35020302034844号

Top