## 一、前言

现在这个时代,智能手机不要太流行,满大街都是,甚至连爷爷奶奶级别的人都会用智能手机,本次要写的控件就是智能手机中的电池电量表示控件,采用纯painter绘制,其实也可以采用贴图,我估计大部分手机上的都是采用贴图的形式,贴图有个好处就是程序员不用操心,drawimage即可,速度非常快。

至于本控件没有任何技术难点,就是自动计算当前设置的电量,根据宽度的比例划分100个等分,每个等分占用多少个像素,然后电量*该比例就是要绘制的电量的区域,可以设置报警电量,低于该变量整个电池电量区域红色显示。

**主要功能:**

1. 可设置开关按钮的样式 圆角矩形/内圆形/外圆形

2. 可设置选中和未选中时的背景颜色

3. 可设置选中和未选中时的滑块颜色

4. 可设置显示的文本

5. 可设置滑块离背景的间隔

6. 可设置圆角角度

7. 可设置是否显示动画过渡效果

## 二、代码思路

void Battery::paintEvent(QPaintEvent *){    //绘制准备工作,启用反锯齿    QPainter painter(this);    painter.setRenderHints(QPainter::Antialiasing | QPainter::TextAntialiasing);    //绘制边框    drawBorder(&painter);    //绘制背景    drawBg(&painter);    //绘制头部    drawHead(&painter);}void Battery::drawBorder(QPainter *painter){    painter->save();    double headWidth = width() / 10;    double batteryWidth = width() - headWidth;    //绘制电池边框    QPointF topLeft(5, 5);    QPointF bottomRight(batteryWidth, height() - 5);    batteryRect = QRectF(topLeft, bottomRight);    painter->setPen(QPen(borderColorStart, 5));    painter->setBrush(Qt::NoBrush);    painter->drawRoundedRect(batteryRect, borderRadius, borderRadius);    painter->restore();}void Battery::drawBg(QPainter *painter){    painter->save();    QLinearGradient batteryGradient(QPointF(0, 0), QPointF(0, height()));    if (currentValue <= alarmValue) {        batteryGradient.setColorAt(0.0, alarmColorStart);        batteryGradient.setColorAt(1.0, alarmColorEnd);    } else {        batteryGradient.setColorAt(0.0, normalColorStart);        batteryGradient.setColorAt(1.0, normalColorEnd);    }    int margin = qMin(width(), height()) / 20;    double unit = (batteryRect.width() - (margin * 2)) / 100;    double width = currentValue * unit;    QPointF topLeft(batteryRect.topLeft().x() + margin, batteryRect.topLeft().y() + margin);    QPointF bottomRight(width + margin + 5, batteryRect.bottomRight().y() - margin);    QRectF rect(topLeft, bottomRight);    painter->setPen(Qt::NoPen);    painter->setBrush(batteryGradient);    painter->drawRoundedRect(rect, bgRadius, bgRadius);    painter->restore();}void Battery::drawHead(QPainter *painter){    painter->save();    QPointF headRectTopLeft(batteryRect.topRight().x(), height() / 3);    QPointF headRectBottomRight(width(), height() - height() / 3);    QRectF headRect(headRectTopLeft, headRectBottomRight);    QLinearGradient headRectGradient(headRect.topLeft(), headRect.bottomLeft());    headRectGradient.setColorAt(0.0, borderColorStart);    headRectGradient.setColorAt(1.0, borderColorEnd);    painter->setPen(Qt::NoPen);    painter->setBrush(headRectGradient);    painter->drawRoundedRect(headRect, headRadius, headRadius);    painter->restore();}

## 三、效果图

3024804dc825ee0cad6f2b8a5b4e2d46.gif

## 四、开源主页

**以上作品完整源码下载都在开源主页,会持续不断更新作品数量和质量,欢迎各位关注。**

1. 国内站点:[https://gitee.com/feiyangqingyun/QWidgetDemo](https://gitee.com/feiyangqingyun/QWidgetDemo)

2. 国际站点:[https://github.com/feiyangqingyun/QWidgetDemo](https://github.com/feiyangqingyun/QWidgetDemo)

3. 个人主页:[https://blog.csdn.net/feiyangqingyun](https://blog.csdn.net/feiyangqingyun)

4. 知乎主页:[https://www.zhihu.com/people/feiyangqingyun/](https://www.zhihu.com/people/feiyangqingyun/)

Logo

开放原子开发者工作坊旨在鼓励更多人参与开源活动,与志同道合的开发者们相互交流开发经验、分享开发心得、获取前沿技术趋势。工作坊有多种形式的开发者活动,如meetup、训练营等,主打技术交流,干货满满,真诚地邀请各位开发者共同参与!

更多推荐