校北仪用于显示不同设备与参照方位之间的误差夹角,如果仅仅使用柱状图显示多个不同设备误差的数值,数据不够直观表示,因此自己画一个,效果如图:
该控件使用QQuickPaintedItem进行绘制后在QML中进行使用,相关部分参数已提供设置接口供QML中调用,如果该控件需要在QWidget中使用,将QQuickPaintedItem修改为QWidget即可。在Demo中演示了如何添加不同方位夹角,不同颜色的指针,并根据指针名称动态修改数据。控件提供的相关接口如下,如果有其他接口需求,可下方留言提供建议,本人不断完善。
属性:
title:设置表盘中文字内容
titlePoint:设置表盘中文字大小
beginAngle:设置表盘刻度起始方位角,默认为(330)
spanAngle:设置表盘刻度拓展角度,默认为(240)
dialTextPoint:设置表盘数字大小
方法:
void appendPointer(const qreal angle, const QColor color, const QString name):往控件中添加新的数据指针【angle:方位夹角(取值范围:-3~3);color:指针颜色;name:指针名称】
void changePointerData(const QString name,const qreal angle):根据指针名修改指针数值
void clear():清除表盘中所有数据指针
void remove(const QString name):根据指针名删除指针
void pointerVisible(const QString name, const bool visible):根据指针名进行隐藏/显示
void showAllPointer():显示所有指针
void hideAllPointer():隐藏所有指针
Demo地址GitHub:
https://github.com/zjgo007/QmlDemo/tree/master/Azimuthhttps://github.com/zjgo007/QmlDemo/tree/master/Azimuth
Demo地址csdn下载:
https://download.csdn.net/download/zjgo007/75943564https://download.csdn.net/download/zjgo007/75943564
部分代码:
绘制paint:
void AzimuthDial::paint(QPainter *painter)
{
painter->setPen(Qt::NoPen);
painter->setRenderHint(QPainter::Antialiasing);
painter->setRenderHint(QPainter::SmoothPixmapTransform);
painter->translate(this->width()/2,this->height()/2);
radius = qMin(this->width(),this->height())/2;
drawBgLightColor(painter);
drawScaleBgColor(painter);
drawSlideBarColor(painter);
drawDialCenterCross(painter);
drawDialRule(painter);
drawDialText(painter);
drawPointer(painter);
drawDialCenterColor(painter);
}
绘制背景颜色:
void AzimuthDial::drawBgLightColor(QPainter *painter)
{
QConicalGradient conicalBrush(0,0,90);
conicalBrush.setColorAt(0,mBgLightColor);
conicalBrush.setColorAt(0.5,mBgLightColor);
conicalBrush.setColorAt(0.12,mBgLightColor);
conicalBrush.setColorAt(0.88,mBgLightColor.darker(40));
conicalBrush.setColorAt(0.4,mBgLightColor.darker(30));
conicalBrush.setColorAt(0.6,mBgLightColor.darker(30));
conicalBrush.setColorAt(0.25,mBgLightColor.darker(160));
conicalBrush.setColorAt(0.75,mBgLightColor.darker(160));
conicalBrush.setColorAt(0.1,mBgLightColor);
painter->setBrush(conicalBrush);
painter->drawEllipse(QPointF(0,0),radius*0.95,radius*0.96);
}
绘制表盘刻度背景条颜色:
void AzimuthDial::drawSlideBarColor(QPainter *painter)
{
QConicalGradient barTintColor(0,0,90);
barTintColor.setColorAt(0,"#4d00fa9a");
barTintColor.setColorAt(0.125,"#4d00ffff");
barTintColor.setColorAt(0.25,"#4dffd700");
barTintColor.setColorAt(0.375,"#4dff4500");
barTintColor.setColorAt(0.5,"#4d00fa9a");
barTintColor.setColorAt(0.625,"#4dff4500");
barTintColor.setColorAt(0.75,"#4dffd700");
barTintColor.setColorAt(0.875,"#4d00ffff");
barTintColor.setColorAt(1,"#4d00fa9a");
QRectF rectT(-0.9*radius,-0.9*radius,radius*1.8,radius*1.8);
qreal subRadiusT = (radius*0.79);
painter->setBrush(barTintColor);
QPainterPath piePathT;
piePathT.arcMoveTo(rectT,mStartAngle);
piePathT.arcTo(rectT,mStartAngle,mSpanAngle);
piePathT.lineTo(0,0);
QPainterPath subPathT;
subPathT.addEllipse(QPointF(0,0),subRadiusT,subRadiusT);
piePathT = piePathT-subPathT;
painter->drawPath(piePathT);
QConicalGradient barColor(0,0,90);
barColor.setColorAt(0,"#00fa9a");
barColor.setColorAt(0.125,"#00ffff");
barColor.setColorAt(0.25,"#ffd700");
barColor.setColorAt(0.375,"#ff4500");
barColor.setColorAt(0.5,"#00fa9a");
barColor.setColorAt(0.625,"#ff4500");
barColor.setColorAt(0.75,"#ffd700");
barColor.setColorAt(0.875,"#00ffff");
barColor.setColorAt(1,"#00fa9a");
QRectF rect(-0.86*radius,-0.86*radius,radius*1.72,radius*1.72);
qreal subRadius = (radius*0.83);
painter->setBrush(barColor);
QPainterPath piePath;
piePath.arcMoveTo(rect,mStartAngle);
piePath.arcTo(rect,mStartAngle,mSpanAngle);
piePath.lineTo(0,0);
QPainterPath subPath;
subPath.addEllipse(QPointF(0,0),subRadius,subRadius);
piePath = piePath-subPath;
painter->drawPath(piePath);
}
绘制中心十字:
void AzimuthDial::drawDialCenterCross(QPainter *painter)
{
qreal crossRadiusBrush = radius*0.65;
painter->setPen(Qt::NoPen);
QLinearGradient gradientH(0,-10,0,10);
QLinearGradient gradientV(-10,0,10,0);
gradientH.setColorAt(0,"#3300fa9a");
gradientH.setColorAt(0.5,"#00fa9a");
gradientH.setColorAt(1,"#3300fa9a");
gradientV.setColorAt(0,"#3300fa9a");
gradientV.setColorAt(0.5,"#00fa9a");
gradientV.setColorAt(1,"#3300fa9a");
painter->setBrush(gradientH);
painter->drawRect(-crossRadiusBrush,-10,crossRadiusBrush*2,20);
painter->setBrush(gradientV);
painter->drawRect(-10,-crossRadiusBrush,20,crossRadiusBrush);
}
绘制表盘刻度线,整数刻度时使用长三角型着重表示:
void AzimuthDial::drawDialRule(QPainter *painter)
{
QPen pen;
pen.setColor(mDialRuleColor);
pen.setWidth(2);
painter->setBrush(mDialRuleColor);
QPainterPath dialRulePath;
qreal intervalAngle = mSpanAngle/30;
qreal pointAngle = mSpanAngle/6;
qreal dialRadius = radius*0.9;
qreal subDiaRadius = radius*0.83;
qreal pointDiaRadius = radius*0.79;
//绘制标尺刻度线
for(int a=0;a<=mSpanAngle;a+=intervalAngle){
qreal currentAngle = a+mStartAngle;
qreal r = qDegreesToRadians(currentAngle);
const qreal x1 = dialRadius*cos(r);
const qreal y1 = -dialRadius*sin(r);
const qreal x2 = subDiaRadius*cos(r);
const qreal y2 = -subDiaRadius*sin(r);
dialRulePath.moveTo(x1,y1);
dialRulePath.lineTo(x2,y2);
}
painter->setPen(pen);
painter->drawPath(dialRulePath);
//绘制整角度时标尺刻度线样式(三角形)旋转坐标轴绘制
qreal pointStartAngle = mStartAngle>180 ? (mStartAngle-360):mStartAngle;
const QPointF pointDial[4]={
QPointF(pointDiaRadius,0),
QPointF(pointDiaRadius,-0),
QPointF(dialRadius,-1),
QPointF(dialRadius,1)
};
for(int i=0;i<=6;i++){
qreal rotateAngle = pointStartAngle+i*pointAngle;
painter->rotate(-rotateAngle);
painter->drawConvexPolygon(pointDial,4);
painter->rotate(rotateAngle);
}
}
绘制表盘数字:
void AzimuthDial::drawDialText(QPainter *painter)
{
QPen pen;
pen.setColor(mDialTextColor);
pen.setWidth(2);
painter->setFont(QFont("Euphemia",mDialTextPoint,QFont::DemiBold));
qreal textDiaRadius = radius*0.71;
qreal textAngle = mSpanAngle/6;
qreal textStartAngle = mStartAngle>180 ? (mStartAngle-360):mStartAngle;
const QStringList labels = {"3","2","1","0","1","2","3"};
for(int i=0;i<=6;i++){
qreal currentAngle = textStartAngle+i*textAngle;
qreal r = qDegreesToRadians(currentAngle);
const qreal x = textDiaRadius*cos(r);
const qreal y = -textDiaRadius*sin(r);
painter->drawText(QRectF(x-15,y-10,30,20),Qt::AlignHCenter|Qt::AlignVCenter,labels.at(i));
}
}
绘制数值指针:
void AzimuthDial::drawPointer(QPainter *painter)
{
painter->setPen(Qt::NoPen);
painter->setBrush(mDialPointerColor);
qreal pointDiaRadius = radius*0.6;
qreal pointBottomRadius = radius*0.1;
const QPointF pointDial[4]={
QPointF(-pointBottomRadius,3),
QPointF(-pointBottomRadius,-3),
QPointF(pointDiaRadius,-1),
QPointF(pointDiaRadius,1),
};
for(auto data : mVector){
qreal angle = data.angle;
QColor color = data.color;
QString name = data.name;
qreal r = 90 - angle*(mSpanAngle/6);
painter->rotate(-r);
painter->setBrush(color);
painter->drawConvexPolygon(pointDial,4);
painter->rotate(r);
}
}
绘制中心圆:
void AzimuthDial::drawDialCenterColor(QPainter *painter)
{
qreal centerRadius = radius*0.08;
QRadialGradient radial(0,0,centerRadius,0,0);
radial.setColorAt(1,mCenterColor.lighter(170));
radial.setColorAt(0.90,mCenterColor.lighter(150));
radial.setColorAt(0.82,mCenterColor.lighter(130));
radial.setColorAt(0.7,mCenterColor);
painter->setBrush(radial);
painter->drawEllipse(QPointF(0,0),centerRadius,centerRadius);
//绘制标签
QPen pen;
pen.setColor(mDialTextColor);
pen.setWidth(2);
painter->setPen(pen);
painter->setFont(QFont("微软雅黑",mTitleTextPoint,QFont::DemiBold));
painter->drawText(QRectF(-100,centerRadius*2,200,60),Qt::AlignHCenter|Qt::AlignVCenter,mTitle);
QImage pixmapGPS(":/gps.png");
painter->drawImage(QRectF(-centerRadius,-centerRadius,centerRadius*2,centerRadius*2),pixmapGPS,QRectF(0,0,79,79));
QImage pixmapLogo(":/logo.png");
painter->drawImage(QRectF(-centerRadius*3.2,centerRadius*2+70,centerRadius*6.4,centerRadius*3),pixmapLogo,QRectF(0,0,300,128));
}
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)