仿 遥控器 摇杆控件
1,项目中 需要对遥控器的 控制进行PC端展示,因此 自己封装了一个 widget。用于摇杆数值的实时展示,效果如下
2,思路
利用 paintEvent(QPaintEvent *) 事件,进行实时绘制,具体实现 如下
头文件
#ifndef JOYSTICK_H
#define JOYSTICK_H
#include <QWidget>
#include "pvgauge_global.h"
class GAUGE_EXPORT Joystick: public QWidget
{
Q_OBJECT
public:
explicit Joystick(QWidget *parent = nullptr);
~Joystick();
/**
* @brief 设置遥控器 量程,默认1000
* @param range
*/
void setRange(int range);
/**
* @brief 设置垂直位置
* @param vValue
*/
void setVValue(int vValue);
/**
* @brief 设置水平位置
* @param hValue
*/
void setHValue(int hValue);
protected:
void paintEvent(QPaintEvent *);
void resizeEvent(QResizeEvent *);
void drawCircle(QPainter *painter);
void drawHVLine(QPainter *painter);
void drawHVPoint(QPainter *painter);
private:
int m_radius;
int m_centerX;
int m_centerY;
int m_range; //遥控器量程
int m_hValue;
int m_vValue;
int m_circleOffset;
int m_pointOffset;
private:
void initData();
};
#endif // JOYSTICK_H
源文件
#include "joystick.h"
#include <QPainter>
#include <QDebug>
Joystick::Joystick(QWidget *parent):QWidget(parent),m_range(1000)
,m_hValue(500),m_vValue(-500)
{
initData();
}
Joystick::~Joystick()
{
}
void Joystick::resizeEvent(QResizeEvent *)
{
initData();
update();
}
void Joystick::paintEvent(QPaintEvent *)
{
QPainter painter(this);
painter.setRenderHint(QPainter::Antialiasing);
painter.translate(width() / 2, height() / 2); /* 坐标变换为窗体中心 */
drawCircle(&painter);//圆
drawHVLine(&painter);//水平 垂直线
drawHVPoint(&painter);//线上 点
}
void Joystick::drawCircle(QPainter *painter)
{
painter->save();
painter->setPen(Qt::NoPen);
/* 外边框 */
int tempRadius=m_radius;
QLinearGradient lg1(0, -tempRadius, 0, tempRadius);
//lg1.setColorAt(0, QColor(255, 255, 255));
//lg1.setColorAt(1, QColor(166, 166, 166));
lg1.setColorAt(0, QColor(111, 111,111));
lg1.setColorAt(1, QColor(111, 111, 111));
painter->setBrush(lg1);
painter->drawEllipse(-tempRadius, -tempRadius, tempRadius << 1, tempRadius << 1);
/* 内边框 */
tempRadius -= m_circleOffset;
QLinearGradient lg2(0, -tempRadius, 0, tempRadius);
// lg2.setColorAt(0, QColor(166, 166, 166));
// lg2.setColorAt(1, QColor(255, 255, 255));
lg2.setColorAt(0, QColor(255, 255, 255));
lg2.setColorAt(1, QColor(255, 255, 255));
painter->setBrush(lg2);
painter->drawEllipse(-tempRadius, -tempRadius, tempRadius << 1, tempRadius << 1);
/* 内部指示颜色 */
tempRadius -= 4;
QRadialGradient rg(0, 0, tempRadius);
// rg.setColorAt(0, QColor(0, 245, 0));
// rg.setColorAt(0.6, QColor(0, 210, 0));
// rg.setColorAt(1, QColor(0, 166, 0));
rg.setColorAt(0, QColor(0, 0, 0,50));
rg.setColorAt(1, QColor(0, 0, 0,50));
painter->setBrush(rg);
painter->drawEllipse(-tempRadius, -tempRadius, tempRadius << 1, tempRadius << 1);
painter->restore();
}
void Joystick::drawHVLine(QPainter *painter)
{
painter->save();
painter->setPen(QColor(100,0,0));
painter->setPen(Qt::DashLine);
int hlineStartX = m_centerX-m_radius+m_circleOffset;
int hlineStartY = m_centerY;
int hlineStopX= m_centerX+m_radius-m_circleOffset;
int hlineStopY= m_centerY;
painter->drawLine(QPoint(hlineStartX+m_circleOffset+m_pointOffset,hlineStartY),QPoint(hlineStopX-m_circleOffset-m_pointOffset,hlineStopY));
int vlineStartX = m_centerX ;
int vlineStartY = m_centerY-m_radius+m_circleOffset;
int vlineStopX=m_centerX;
int vlineStopY=m_centerY+m_radius-m_circleOffset;
painter->drawLine(QPoint(vlineStartX,vlineStartY+m_circleOffset+m_pointOffset),QPoint(vlineStopX,vlineStopY-m_circleOffset-m_pointOffset));
painter->restore();
}
void Joystick::drawHVPoint(QPainter *painter)
{
painter->save();
int circleRadius=m_pointOffset*2;//圆点半径
QBrush brush(QColor(0,255,255));
painter->setBrush(brush);
//水平点
int hx=(m_hValue*(m_radius-m_circleOffset*2))/m_range;
painter->drawEllipse(QPoint(hx,m_centerY),circleRadius,circleRadius);
QBrush brush2(QColor(0,255,64));
painter->setBrush(brush2);
//垂直点
int vY=(m_vValue*(m_radius-m_circleOffset*2))/m_range;
painter->drawEllipse(QPoint(m_centerX,vY),circleRadius,circleRadius);
painter->setPen(QColor(0,0,0));
//水平文字
painter->drawText(QPoint(hx-circleRadius,m_centerY+circleRadius*2+m_pointOffset),QString::number(m_hValue));
//垂直文字
painter->drawText(QPoint(m_centerX+circleRadius+m_pointOffset,vY+m_pointOffset),QString::number(-m_vValue));
painter->restore();
}
void Joystick::setHValue(int hValue)
{
m_hValue = hValue;
update();
}
void Joystick::setVValue(int vValue)
{
m_vValue = -vValue;
update();
}
void Joystick::setRange(int range)
{
m_range = range;
}
void Joystick::initData()
{
m_radius = qMin(width()/2, height()/2);//半径
//圆心
m_centerX = 0;
m_centerY = 0;
m_circleOffset= m_radius/20+2;// 13;//内外圆 之差
m_pointOffset=m_radius/50+2;// 5;//点 与文字的偏移
}