当前位置:网站首页>Qt编写自定义控件-自绘电池
Qt编写自定义控件-自绘电池
2022-07-01 05:35:00 【my_angle2016】
完整代码
battery.h
#ifndef BATTERY_H
#define BATTERY_H
#include <QMainWindow>
class Battery : public QMainWindow
{
Q_OBJECT
public:
Battery(QWidget *parent = nullptr);
~Battery();
void SetValue(int currentValue);
int GetValue();
protected:
void paintEvent(QPaintEvent *);
void drawBorder(QPainter *painter);
void drawBg(QPainter *painter);
void drawText(QPainter *painter);
private slots:
void inputValue();
private:
double _currentValue;
int _margin;
double _minValue; //最小值
double _maxValue; //最大值
bool _isForward; //是否往前移
int _batteryWidth;
int _batteryHeight;
QRectF batteryRect; //电池主体区域
QTimer *inputTimer; //绘制定时器
};
#endif // BATTERY_H
battery.cpp
#pragma execution_character_set("utf-8")
#include "battery.h"
#include "qpainter.h"
#include "qtimer.h"
#include "qdebug.h"
Battery::Battery(QWidget *parent)
: QMainWindow(parent)
, _currentValue(10)
, _margin(3)
, _minValue(0)
, _maxValue(100)
, _isForward(true)
, _batteryWidth(50)
, _batteryHeight(20)
{
// ui->setupUi(this); //驱动UI设计师
// setFixedSize(300, 180); //固定大小
setBaseSize(350, 180);
///--设置了个定时器,周期 10ms ,输入值 inputValue()
inputTimer = new QTimer(this);
inputTimer->setInterval(100);
connect(inputTimer, SIGNAL(timeout()), this, SLOT(inputValue())); //定时100ms调用1次inputValue
inputTimer->start();
}
Battery::~Battery()
{
if (inputTimer->isActive()) {
inputTimer->stop();
}
}
void Battery::SetValue(int currentValue)
{
_currentValue = currentValue;
}
int Battery::GetValue()
{
return _currentValue;
}
///--1. 绘制事件
/*只要窗口部件需要被重绘就被调用, 每个要显示输出的窗口部件必须实现它。
这个事件处理器可以在子类中被重新实现来接收绘制事件。 它可以是repaint()或update()的结果。
很多窗口部件在当它们被请求时,它们很简单地重新绘制整个界面,但是一些窗口部件通过仅仅绘制被请求的区域QPaintEvent::region()进行优化,例如,QListView和QCanvas就是这样做的。
原文链接:https://blog.csdn.net/u012151242/article/details/78947024
*/
void Battery::paintEvent(QPaintEvent *)
{
//绘制准备工作,启用反锯齿
QPainter painter(this);
painter.setRenderHints(QPainter::Antialiasing | QPainter::TextAntialiasing);
///--1.1 绘制边框和头部
drawBorder(&painter);
///--1.2 绘制填充
drawBg(&painter);
///--1.3 内部百分比
drawText(&painter);
}
///--1.1 绘制边框和头部
void Battery::drawBorder(QPainter *painter)
{
//保存状态
painter->save();
//设置笔的颜色和粗细
painter->setPen(QPen(Qt::gray, 5));
//没有画刷填充
painter->setBrush(Qt::NoBrush);
//绘制给定的圆角矩形 矩形 xRadius yRadius
// painter->drawRoundedRect(batteryRect, borderRadius, borderRadius);
//电池边框居中
batteryRect = QRectF((width()-_batteryWidth)/2, (height()-_batteryHeight)/2, _batteryWidth, _batteryHeight);
painter->drawRoundedRect(batteryRect, 2, 2);
//电池头部:画一条直线
painter->setPen(QPen(Qt::gray, 5));
QLineF line(batteryRect.topRight().x()+5, batteryRect.topRight().y()+5, batteryRect.topRight().x()+5, batteryRect.bottomRight().y()-5);
painter->drawLine(line);
//回复保存的状态
painter->restore();
}
///--1.2 绘制填充
void Battery::drawBg(QPainter *painter)
{
painter->save();
//确定画刷颜色
if(_currentValue<=10) {
painter->setBrush(QColor(204, 38, 38)); //红
}
else if (_currentValue <= 20) {
painter->setBrush(QColor(198, 163, 0)); //黄
}
else {
painter->setBrush(QColor(50, 205, 51)); //绿
}
//当前电量转化为宽
double width = _currentValue * (batteryRect.width() - (_margin * 2)) / 100;
//确定左上角位置
QPointF topLeft(batteryRect.topLeft().x() + _margin, batteryRect.topLeft().y() + _margin);
//确定变化的右下角, 最小给个10, 显示内部的填充
QPointF bottomRight(batteryRect.topLeft().x() + width + _margin, batteryRect.bottomRight().y() - _margin);
QRectF rect(topLeft, bottomRight);
//没有线宽
painter->setPen(Qt::NoPen);
painter->drawRoundedRect(rect, 5, 5);
painter->restore();
}
///--1.3 内部百分比
void Battery::drawText(QPainter *painter) {
painter->save();
painter->setPen(Qt::black);
painter->setFont(QFont("Arial",11));
QString value = QString::number(_currentValue) + "%";
//文本居中的好方法
painter->drawText(batteryRect,Qt::AlignCenter,value);
painter->restore();
}
//1. 驱动、输入
void Battery::inputValue()
{
/* if(_isForward) _currentValue += 1;
else _currentValue -= 1;
if(_currentValue >= 45) {
_currentValue = 45;
_isForward = false;
}
if(_currentValue <= _minValue) {
_currentValue = _minValue;
_isForward = true;
}*/
_currentValue = GetValue();
if(_currentValue >= 100) {
_currentValue = 100;
_isForward = false;
}
if(_currentValue <= _minValue) {
_currentValue = _minValue;
_isForward = true;
}
//重绘,将调用paintEvent()函数
this->update();
}
调用过程
widget.cpp
#include "widget.h"
#include "ui_widget.h"
#include "battery.h"
Battery *battery;
int g_currentValue = 10;
Widget::Widget(QWidget *parent)
: QWidget(parent)
, ui(new Ui::Widget)
{
ui->setupUi(this);
battery = new Battery();
battery->setGeometry(rect().x()+500, rect().y()+10,
400, 300);
battery->setParent(this);
inputTimer = new QTimer(this);
inputTimer->setInterval(100);
connect(inputTimer, SIGNAL(timeout()), this, SLOT(inputValue())); //定时100ms调用1次inputValue
inputTimer->start();
}
Widget::~Widget()
{
delete ui;
}
void Widget::inputValue()
{
if(g_currentValue <=0)
g_currentValue = 100;
else
g_currentValue -=1;
battery->SetValue(g_currentValue);
}运行效果截图

边栏推荐
- Rust hello-word
- ssm+mysql二手交易网站(论文+源码获取链接)
- [excel] column operation, which performs specific column for data in a cell, such as text division by comma, colon, space, etc
- Wild melon or split melon?
- Printk debugging summary
- 加密狗资料搜集
- MySQL converts milliseconds to time string
- JDBC常见面试题
- 使用 Nocalhost 开发 Rainbond 上的微服务应用
- 如何创建一个根据进度改变颜色的进度条
猜你喜欢

导数的左右极限和左右导数的辨析

ssm+mysql二手交易网站(论文+源码获取链接)

Usage and principle of synchronized

Leetcode top 100 question 2 Add two numbers

Learn the customization and testing of fpga---ram IP from the bottom structure

在Rainbond中一键部署高可用 EMQX 集群

el-cascader回显失败;el-cascader回显不出来

One click deployment of highly available emqx clusters in rainbow

了解 JVM 中几个相关问题 — JVM 内存布局、类加载机制、垃圾回收
![[QT] QT after addition, subtraction, multiplication and division, two decimal places are reserved](/img/30/c802ae9b65601832bf52e760e9962d.png)
[QT] QT after addition, subtraction, multiplication and division, two decimal places are reserved
随机推荐
Memtable for leveldb source code analysis
Thread process foundation of JUC
运行时候的导包搜索路径虽然pycharm中标红但不影响程序的执行
Practice of combining rook CEPH and rainbow, a cloud native storage solution
Simple implementation of database connection pool
提高企业产品交付效率系列(1)—— 企业应用一键安装和升级
Educational administration management system (free source code)
Rust hello-word
Qt编译时,出现 first defined here,原因及解决方法
[excel] column operation, which performs specific column for data in a cell, such as text division by comma, colon, space, etc
Causes of short circuit of conductive slip ring and Countermeasures
Redis数据库的部署及常用命令
HDU - 1024 Max Sum Plus Plus(DP)
Rust基础入门之变量绑定与解构
Variable binding and deconstruction for rudimentary rust
Spanner 论文小结
Rust hello-word
【考研高数 武忠祥+880版 自用】高数第二章基础阶段思维导图
导数的左右极限和左右导数的辨析
boot+jsp的高校社團管理系統(附源碼下載鏈接)