Qt绘制指南针(仪表盘绘制封装利用)

打印 上一主题 下一主题

主题 654|帖子 654|积分 1962

        指南针是一种用来确定方向的工具。它由一个磁针制成,其一端被磁化,可以自由旋转。当放置在水平面上时,磁针会指向地球的磁北极。通过观察磁针的指向,我们可以确定地理北方的方向。本示例是在Qt中绘制一个指南针,通过继承QWidget类,并重写其paintEvent函数来实现。并对仪表盘绘制举行封装。
一、简述

         这个示例创建了一个名为CompassWidget的自定义小部件,它继承自QWidget类。在paintEvent()函数中,我们利用QPainter类举行绘图操纵。
二、 计划思绪    


  • 创建一个QWidget子类CompassWidget用于绘制指南针。
  • 在CompassWidget的构造函数中,设置指南针的配景色、大小等属性。
  • 定义QcGaugeWidget类,绘制指南针的各个构成部分,重写干系部件的paintEvent()函数。
  • 利用QPainter在paintEvent()函数中绘制指南针的主体部分,包括圆形配景、指针和刻度。
  • 根据指南针的当前角度,盘算并绘制指针的位置和角度。
  • 添加一个public的setCurrentValue()函数,用于设置指南针的角度,并在此中调用update()函数刷新界面。
三、结果 

 

四、核心代码  

1、头文件

        compasswidget.h 指南针表盘控件
  
  1. #ifndef COMPASSWIDGET_H
  2. #define COMPASSWIDGET_H
  3. #include <QWidget>
  4. class QcGaugeWidget;
  5. class QcNeedleItem;
  6. class QVBoxLayout;
  7. class CompassWidget : public QWidget
  8. {
  9.     Q_OBJECT
  10. public:
  11.     explicit CompassWidget(QWidget *parent = 0);
  12.     ~CompassWidget();
  13. public slots:
  14.     void setCurrentValue(int value);
  15. private:
  16.     void init();
  17. private:
  18.     QcGaugeWidget   *m_pCompassGauge; //表盘
  19.     QcNeedleItem    *m_pCompassNeedle; //指针
  20.     QVBoxLayout     *m_pMainLayout;
  21. };
  22. #endif // COMPASSWIDGET_H
复制代码
qcgaugewidget.h 仪表盘绘制封装(此处只有绘制指南针所需代码,全部代码请下载) 
  
  1. #ifndef QCGAUGEWIDGET_H
  2. #define QCGAUGEWIDGET_H
  3. #include <QWidget>
  4. #include <QPainter>
  5. #include <QObject>
  6. #include <QRectF>
  7. #include <QtMath>
  8. class QcGaugeWidget;
  9. class QcItem;
  10. class QcBackgroundItem;
  11. class QcDegreesItem;
  12. class QcNeedleItem;
  13. class QcLabelItem;
  14. class QcGlassItem;
  15. ///
  16. class QcGaugeWidget : public QWidget
  17. {
  18.     Q_OBJECT
  19. public:
  20.     explicit QcGaugeWidget(QWidget *parent = 0);   
  21.     QcBackgroundItem* addBackground(float position);
  22.     QcDegreesItem* addDegrees(float position);
  23.     QcNeedleItem* addNeedle(float position);
  24.     QcLabelItem* addLabel(float position);
  25.     QcGlassItem* addGlass(float position);
  26.     void addItem(QcItem* item, float position);
  27.     int removeItem(QcItem* item);
  28.     QList <QcItem*> items();
  29.     QList <QcItem*> mItems;
  30. private:
  31.     void paintEvent(QPaintEvent *);
  32. };
  33. ///
  34. class QcItem : public QObject
  35. {
  36.     Q_OBJECT
  37. public:
  38.     explicit QcItem(QObject *parent = 0);
  39.     virtual void draw(QPainter *) = 0;
  40.     virtual int type();
  41.     void setPosition(float percentage);
  42.     float position();
  43.     QRectF rect();
  44.     enum Error{InvalidValueRange,InvalidDegreeRange,InvalidStep};
  45. protected:
  46.     QRectF adjustRect(float percentage);
  47.     float getRadius(const QRectF &);
  48.     float getAngle(const QPointF&, const QRectF &tmpRect);
  49.     QPointF getPoint(float deg, const QRectF &tmpRect);
  50.     QRectF resetRect();
  51.     void update();
  52. private:
  53.     QRectF mRect;
  54.     QWidget *parentWidget;
  55.     float mPosition;
  56. };
  57. ///
  58. class QcScaleItem : public QcItem
  59. {
  60.     Q_OBJECT
  61. public:
  62.     explicit QcScaleItem(QObject *parent = 0);
  63.     void setValueRange(float minValue,float maxValue);
  64.     void setDgereeRange(float minDegree,float maxDegree);
  65.     void setMinValue(float minValue);
  66.     void setMaxValue(float maxValue);
  67.     void setMinDegree(float minDegree);
  68.     void setMaxDegree(float maxDegree);
  69. protected:
  70.     float getDegFromValue(float);
  71.     float mMinValue;
  72.     float mMaxValue;
  73.     float mMinDegree;
  74.     float mMaxDegree;
  75. };
  76. ///
  77. class QcBackgroundItem : public QcItem
  78. {
  79.     Q_OBJECT
  80. public:
  81.     explicit QcBackgroundItem(QObject *parent = 0);
  82.     void draw(QPainter*);
  83.     void addColor(float position, const QColor& color);
  84.     void clearrColors();
  85. private:
  86.     QPen mPen;
  87.     QList<QPair<float,QColor> > mColors;
  88.     QLinearGradient mLinearGrad;
  89. };
  90. ///
  91. class QcGlassItem : public QcItem
  92. {
  93.     Q_OBJECT
  94. public:
  95.     explicit QcGlassItem(QObject *parent = 0);
  96.     void draw(QPainter*);
  97. };
  98. ///
  99. class QcLabelItem : public QcItem
  100. {
  101.     Q_OBJECT
  102. public:
  103.     explicit QcLabelItem(QObject *parent = 0);
  104.     virtual void draw(QPainter *);
  105.     void setAngle(float);
  106.     float angle();
  107.     void setText(const QString &text, bool repaint = true);
  108.     QString text();
  109.     void setColor(const QColor& color);
  110.     QColor color();
  111. private:
  112.     float mAngle;
  113.     QString mText;
  114.     QColor mColor;
  115. };
  116. ///
  117. class  QcDegreesItem : public QcScaleItem
  118. {
  119.     Q_OBJECT
  120. public:
  121.     explicit QcDegreesItem(QObject *parent = 0);
  122.     void draw(QPainter *painter);
  123.     void setStep(float step);
  124.     void setColor(const QColor& color);
  125.     void setSubDegree(bool );
  126. private:
  127.     float mStep;
  128.     QColor mColor;
  129.     bool mSubDegree;
  130. };
  131. ///
  132. class QcNeedleItem : public QcScaleItem
  133. {
  134.     Q_OBJECT
  135. public:
  136.     explicit QcNeedleItem(QObject *parent = 0);
  137.     void draw(QPainter*);
  138.     void setCurrentValue(float value);
  139.     float currentValue();
  140.     void setValueFormat(QString format);
  141.     QString currentValueFormat();
  142.     void setColor(const QColor & color);
  143.     QColor color();
  144.     void setLabel(QcLabelItem*);
  145.     QcLabelItem * label();
  146.     enum NeedleType{
  147.         DiamonNeedle,
  148.         TriangleNeedle,//三角指针
  149.         FeatherNeedle,
  150.         AttitudeMeterNeedle,
  151.         CompassNeedle   //指南针
  152.     };
  153.     void setNeedle(QcNeedleItem::NeedleType needleType);
  154. private:
  155.     QPolygonF mNeedlePoly;
  156.     float mCurrentValue;
  157.     QColor mColor;
  158.     void createDiamonNeedle(float r);
  159.     void createTriangleNeedle(float r);
  160.     void createFeatherNeedle(float r);
  161.     void createAttitudeNeedle(float r);
  162.     void createCompassNeedle(float r);
  163.     NeedleType mNeedleType;
  164.     QcLabelItem *mLabel;
  165.     QString mFormat;
  166. };
  167. #endif // QCGAUGEWIDGET_H
复制代码
2、实当代码

compasswidget.cpp 
  
  1. #include "compasswidget.h"
  2. #include <QVBoxLayout>
  3. #include "qcgaugewidget.h"
  4. CompassWidget::CompassWidget(QWidget *parent)
  5.     : QWidget(parent)
  6. {
  7.     init();
  8. }
  9. CompassWidget::~CompassWidget()
  10. {
  11. }
  12. void CompassWidget::setCurrentValue(int value)
  13. {
  14.     m_pCompassNeedle->setCurrentValue(value);
  15. }
  16. void CompassWidget::init()
  17. {
  18.     m_pCompassGauge = new QcGaugeWidget;
  19.     m_pCompassGauge->addBackground(99);
  20.     QcBackgroundItem *bkg1 = m_pCompassGauge->addBackground(92);
  21.     bkg1->clearrColors();
  22.     bkg1->addColor(0.1,Qt::black);
  23.     bkg1->addColor(1.0,Qt::white);
  24.     QcBackgroundItem *bkg2 = m_pCompassGauge->addBackground(88);
  25.     bkg2->clearrColors();
  26.     bkg2->addColor(0.1,Qt::white);
  27.     bkg2->addColor(1.0,Qt::black);
  28.     QcLabelItem *w = m_pCompassGauge->addLabel(80);//标签
  29.     w->setText("W");
  30.     w->setAngle(0);
  31.     w->setColor(Qt::white);
  32.     QcLabelItem *n = m_pCompassGauge->addLabel(80);
  33.     n->setText("N");
  34.     n->setAngle(90);
  35.     n->setColor(Qt::white);
  36.     QcLabelItem *e = m_pCompassGauge->addLabel(80);
  37.     e->setText("E");
  38.     e->setAngle(180);
  39.     e->setColor(Qt::white);
  40.     QcLabelItem *s = m_pCompassGauge->addLabel(80);
  41.     s->setText("S");
  42.     s->setAngle(270);
  43.     s->setColor(Qt::white);
  44.     QcDegreesItem *deg = m_pCompassGauge->addDegrees(70);//刻度
  45.     deg->setStep(5);
  46.     deg->setMaxDegree(270);
  47.     deg->setMinDegree(-75);
  48.     deg->setColor(Qt::white);
  49.     m_pCompassNeedle = m_pCompassGauge->addNeedle(60);//指针
  50.     m_pCompassNeedle->setNeedle(QcNeedleItem::CompassNeedle);
  51.     m_pCompassNeedle->setValueRange(0,360);
  52.     m_pCompassNeedle->setMaxDegree(360);
  53.     m_pCompassNeedle->setMinDegree(0);
  54.     m_pCompassGauge->addBackground(7);
  55.     m_pCompassGauge->addGlass(88);//毛玻璃
  56.     m_pMainLayout = new QVBoxLayout(this);
  57.     m_pMainLayout->addWidget(m_pCompassGauge);
  58. }
复制代码
qcgaugewidget.cpp  仪表盘绘制封装(此处只有绘制指南针所需代码,全部代码请下载) 
  1. #include "qcgaugewidget.h"
  2. QcGaugeWidget::QcGaugeWidget(QWidget *parent) :
  3.     QWidget(parent)
  4. {
  5.     setMinimumSize(250,250);
  6. }
  7. QcBackgroundItem *QcGaugeWidget::addBackground(float position)
  8. {
  9.     QcBackgroundItem * item = new QcBackgroundItem(this);
  10.     item->setPosition(position);
  11.     mItems.append(item);
  12.     return item;
  13. }
  14. QcDegreesItem *QcGaugeWidget::addDegrees(float position)
  15. {
  16.     QcDegreesItem * item = new QcDegreesItem(this);
  17.     item->setPosition(position);
  18.     mItems.append(item);
  19.     return item;
  20. }
  21. QcNeedleItem *QcGaugeWidget::addNeedle(float position)
  22. {
  23.     QcNeedleItem * item = new QcNeedleItem(this);
  24.     item->setPosition(position);
  25.     mItems.append(item);
  26.     return item;
  27. }
  28. QcLabelItem *QcGaugeWidget::addLabel(float position)
  29. {
  30.     QcLabelItem * item = new QcLabelItem(this);
  31.     item->setPosition(position);
  32.     mItems.append(item);
  33.     return item;
  34. }
  35. QcGlassItem *QcGaugeWidget::addGlass(float position)
  36. {
  37.     QcGlassItem * item = new QcGlassItem(this);
  38.     item->setPosition(position);
  39.     mItems.append(item);
  40.     return item;
  41. }
  42. void QcGaugeWidget::addItem(QcItem *item,float position)
  43. {
  44.     item->setParent(this);
  45.     item->setPosition(position);
  46.     mItems.append(item);
  47. }
  48. int QcGaugeWidget::removeItem(QcItem *item)
  49. {
  50.    return mItems.removeAll(item);
  51. }
  52. QList<QcItem *> QcGaugeWidget::items()
  53. {
  54.     return mItems;
  55. }
  56. void QcGaugeWidget::paintEvent(QPaintEvent */*paintEvt*/)
  57. {
  58.     QPainter painter(this);
  59.     painter.setRenderHint(QPainter::Antialiasing);
  60.     foreach (QcItem * item, mItems) {
  61.         item->draw(&painter);
  62.     }
  63. }
  64. ///
  65. QcItem::QcItem(QObject *parent) :
  66.     QObject(parent)
  67. {
  68.     parentWidget = qobject_cast<QWidget*>(parent);
  69.     mPosition = 50;
  70. }
  71. int QcItem::type()
  72. {
  73.     return 50;
  74. }
  75. void QcItem::update()
  76. {
  77.     parentWidget->update();
  78. }
  79. float QcItem::position()
  80. {
  81.     return mPosition;
  82. }
  83. QRectF QcItem::rect()
  84. {
  85.     return mRect;
  86. }
  87. void QcItem::setPosition(float position)
  88. {
  89.     if(position>100)
  90.         mPosition = 100;
  91.     else if(position<0)
  92.         mPosition = 0;
  93.     else
  94.         mPosition = position;
  95.     update();
  96. }
  97. QRectF QcItem::adjustRect(float percentage)
  98. {
  99.     float r = getRadius(mRect);
  100.     float offset =   r-(percentage*r)/100.0;
  101.     QRectF tmpRect = mRect.adjusted(offset,offset,-offset,-offset);
  102.     return tmpRect;
  103. }
  104. float QcItem::getRadius(const QRectF &tmpRect)
  105. {
  106.     float r = 0;
  107.     if(tmpRect.width()<tmpRect.height())
  108.         r = tmpRect.width()/2.0;
  109.     else
  110.         r = tmpRect.height()/2.0;
  111.     return r;
  112. }
  113. QRectF QcItem::resetRect()
  114. {
  115.     mRect = parentWidget->rect();
  116.     float r = getRadius(mRect);
  117.     mRect.setWidth(2.0*r);
  118.     mRect.setHeight(2.0*r);
  119.     mRect.moveCenter(parentWidget->rect().center());
  120.     return mRect;
  121. }
  122. QPointF QcItem::getPoint(float deg,const QRectF &tmpRect)
  123. {
  124.     float r = getRadius(tmpRect);
  125.     float xx=cos(qDegreesToRadians(deg))*r;
  126.     float yy=sin(qDegreesToRadians(deg))*r;
  127.     QPointF pt;
  128.     xx=tmpRect.center().x()-xx;
  129.     yy=tmpRect.center().y()-yy;
  130.     pt.setX(xx);
  131.     pt.setY(yy);
  132.     return pt;
  133. }
  134. float QcItem::getAngle(const QPointF&pt, const QRectF &tmpRect)
  135. {
  136.     float xx=tmpRect.center().x()-pt.x();
  137.     float yy=tmpRect.center().y()-pt.y();
  138.     return qRadiansToDegrees( atan2(yy,xx));
  139. }
  140. ///
  141. QcScaleItem::QcScaleItem(QObject *parent) :
  142.     QcItem(parent)
  143. {
  144.     mMinDegree = -45;
  145.     mMaxDegree = 225;
  146.     mMinValue = 0;
  147.     mMaxValue = 100;
  148. }
  149. void QcScaleItem::setValueRange(float minValue, float maxValue)
  150. {
  151.     if(!(minValue<maxValue))
  152.         throw( InvalidValueRange);
  153.     mMinValue = minValue;
  154.     mMaxValue = maxValue;
  155. }
  156. void QcScaleItem::setDgereeRange(float minDegree, float maxDegree)
  157. {
  158.     if(!(minDegree<maxDegree))
  159.         throw( InvalidValueRange);
  160.     mMinDegree = minDegree;
  161.     mMaxDegree = maxDegree;
  162. }
  163. float QcScaleItem::getDegFromValue(float v)
  164. {
  165.     float a = (mMaxDegree-mMinDegree)/(mMaxValue-mMinValue);
  166.     float b = -a*mMinValue+mMinDegree;
  167.     return a*v+b;
  168. }
  169. void QcScaleItem::setMinValue(float minValue)
  170. {
  171.     if(minValue>mMaxValue)
  172.         throw (InvalidValueRange);
  173.     mMinValue = minValue;
  174.     update();
  175. }
  176. void QcScaleItem::setMaxValue(float maxValue)
  177. {
  178.     if(maxValue<mMinValue )
  179.         throw (InvalidValueRange);
  180.     mMaxValue = maxValue;
  181.     update();
  182. }
  183. void QcScaleItem::setMinDegree(float minDegree)
  184. {
  185.     if(minDegree>mMaxDegree)
  186.         throw (InvalidDegreeRange);
  187.     mMinDegree = minDegree;
  188.     update();
  189. }
  190. void QcScaleItem::setMaxDegree(float maxDegree)
  191. {
  192.     if(maxDegree<mMinDegree)
  193.         throw (InvalidDegreeRange);
  194.     mMaxDegree = maxDegree;
  195.     update();
  196. }
  197. ///
  198. QcBackgroundItem::QcBackgroundItem(QObject *parent) :
  199.     QcItem(parent)
  200. {
  201.     setPosition(88);
  202.     mPen = Qt::NoPen;
  203.     setPosition(88);
  204.     addColor(0.4,Qt::darkGray);
  205.     addColor(0.8,Qt::black);
  206. }
  207. void QcBackgroundItem::draw(QPainter* painter)
  208. {
  209.     QRectF tmpRect = resetRect();
  210.     painter->setBrush(Qt::NoBrush);
  211.     QLinearGradient linearGrad(tmpRect.topLeft(), tmpRect.bottomRight());
  212.     for(int i = 0;i<mColors.size();i++){
  213.         linearGrad.setColorAt(mColors[i].first,mColors[i].second);
  214.     }
  215.     painter->setPen(mPen);
  216.     painter->setBrush(linearGrad);
  217.     painter->drawEllipse(adjustRect(position()));
  218. }
  219. void QcBackgroundItem::addColor(float position, const QColor &color)
  220. {
  221.     if(position<0||position>1)
  222.         return;
  223.       QPair<float,QColor> pair;
  224.       pair.first = position;
  225.       pair.second = color;
  226.       mColors.append(pair);
  227.       update();
  228. }
  229. void QcBackgroundItem::clearrColors()
  230. {
  231.     mColors.clear();
  232. }
  233. ///
  234. QcGlassItem::QcGlassItem(QObject *parent) :
  235.     QcItem(parent)
  236. {
  237.     setPosition(88);
  238. }
  239. void QcGlassItem::draw(QPainter *painter)
  240. {
  241.     resetRect();
  242.     QRectF tmpRect1 = adjustRect(position());
  243.     QRectF tmpRect2 = tmpRect1;
  244.     float r = getRadius(tmpRect1);
  245.     tmpRect2.setHeight(r/2.0);
  246.     painter->setPen(Qt::NoPen);
  247.     QColor clr1 = Qt::gray ;
  248.     QColor clr2 = Qt::white;
  249.     clr1.setAlphaF(0.2);
  250.     clr2.setAlphaF(0.4);
  251.     QLinearGradient linearGrad1(tmpRect1.topLeft(), tmpRect1.bottomRight());
  252.     linearGrad1.setColorAt(0.1, clr1);
  253.     linearGrad1.setColorAt(0.5, clr2);
  254.     painter->setBrush(linearGrad1);
  255.     painter->drawPie(tmpRect1,0,16*180);
  256.     tmpRect2.moveCenter(rect().center());
  257.     painter->drawPie(tmpRect2,0,-16*180);
  258. }
  259. ///
  260. QcLabelItem::QcLabelItem(QObject *parent) :
  261.     QcItem(parent)
  262. {
  263.     setPosition(50);
  264.     mAngle = 270;
  265.     mText = "%";
  266.     mColor = Qt::black;
  267. }
  268. void QcLabelItem::draw(QPainter *painter)
  269. {
  270.     resetRect();
  271.     QRectF tmpRect = adjustRect(position());
  272.     float r = getRadius(rect());
  273.     QFont font("Meiryo UI", r/10.0, QFont::Bold);
  274.     painter->setFont(font);
  275.     painter->setPen(QPen(mColor));
  276.     QPointF txtCenter = getPoint(mAngle,tmpRect);
  277.     QFontMetrics fMetrics = painter->fontMetrics();
  278.     QSize sz = fMetrics.size( Qt::TextSingleLine, mText );
  279.     QRectF txtRect(QPointF(0,0), sz );
  280.     txtRect.moveCenter(txtCenter);
  281.     painter->drawText( txtRect, Qt::TextSingleLine,mText );
  282. }
  283. void QcLabelItem::setAngle(float a)
  284. {
  285.     mAngle = a;
  286.     update();
  287. }
  288. float QcLabelItem::angle()
  289. {
  290.     return mAngle;
  291. }
  292. void QcLabelItem::setText(const QString &text, bool repaint)
  293. {
  294.     mText = text;
  295.     if(repaint)
  296.         update();
  297. }
  298. QString QcLabelItem::text()
  299. {
  300.     return mText;
  301. }
  302. void QcLabelItem::setColor(const QColor &color)
  303. {
  304.     mColor = color;
  305.     update();
  306. }
  307. QColor QcLabelItem::color()
  308. {
  309.     return mColor;
  310. }
  311. ///
  312. QcDegreesItem::QcDegreesItem(QObject *parent) :
  313.     QcScaleItem(parent)
  314. {
  315.     mStep = 10;
  316.     mColor = Qt::black;
  317.     mSubDegree = false;
  318.     setPosition(90);
  319. }
  320. void QcDegreesItem::draw(QPainter *painter)
  321. {
  322.     resetRect();
  323.     QRectF tmpRect = adjustRect(position());
  324.     painter->setPen(mColor);
  325.     float r = getRadius(tmpRect);
  326.     for(float val = mMinValue;val<=mMaxValue;val+=mStep){
  327.         float deg = getDegFromValue(val);
  328.         QPointF pt = getPoint(deg,tmpRect);
  329.         QPainterPath path;
  330.         path.moveTo(pt);
  331.         path.lineTo(tmpRect.center());
  332.         pt = path.pointAtPercent(0.03);
  333.         QPointF newPt = path.pointAtPercent(0.13);
  334.         QPen pen;
  335.         pen.setColor(mColor);
  336.         if(!mSubDegree)
  337.             pen.setWidthF(r/25.0);
  338.         painter->setPen(pen);
  339.         painter->drawLine(pt,newPt);
  340.     }
  341. }
  342. void QcDegreesItem::setStep(float step)
  343. {
  344.     mStep = step;
  345.     update();
  346. }
  347. void QcDegreesItem::setColor(const QColor& color)
  348. {
  349.     mColor = color;
  350.     update();
  351. }
  352. void QcDegreesItem::setSubDegree(bool b)
  353. {
  354.     mSubDegree = b;
  355.     update();
  356. }
  357. ///
  358. QcNeedleItem::QcNeedleItem(QObject *parent) :
  359.     QcScaleItem(parent)
  360. {
  361.     mCurrentValue = 0;
  362.     mColor = Qt::black;
  363.     mLabel = NULL;
  364.     mNeedleType = FeatherNeedle;
  365. }
  366. void QcNeedleItem::draw(QPainter *painter)
  367. {
  368.     resetRect();
  369.     QRectF tmpRect = adjustRect(position());
  370.     painter->save();
  371.     painter->translate(tmpRect.center());
  372.     float deg = getDegFromValue( mCurrentValue);
  373.     painter->rotate(deg+90.0);
  374.     painter->setBrush(QBrush(mColor));
  375.     painter->setPen(Qt::NoPen);
  376.     QLinearGradient grad;
  377.     switch (mNeedleType) {
  378.     case QcNeedleItem::FeatherNeedle:
  379.         createFeatherNeedle(getRadius(tmpRect));
  380.         break;
  381.     case QcNeedleItem::DiamonNeedle:
  382.         createDiamonNeedle(getRadius(tmpRect));
  383.         break;
  384.     case QcNeedleItem::TriangleNeedle:
  385.         createTriangleNeedle(getRadius(tmpRect));
  386.         break;
  387.     case QcNeedleItem::AttitudeMeterNeedle:
  388.         createAttitudeNeedle(getRadius(tmpRect));
  389.         break;
  390.     case QcNeedleItem::CompassNeedle:
  391.         createCompassNeedle(getRadius(tmpRect));
  392.         grad.setStart(mNeedlePoly[0]);
  393.         grad.setFinalStop(mNeedlePoly[1]);
  394.         grad.setColorAt(0.9,Qt::red);
  395.         grad.setColorAt(1,Qt::blue);
  396.         painter->setBrush(grad);
  397.         break;
  398.     default:
  399.         break;
  400.     }
  401.     painter->drawConvexPolygon(mNeedlePoly);
  402.     painter->restore();
  403. }
  404. void QcNeedleItem::setCurrentValue(float value)
  405. {
  406.        if(value<mMinValue)
  407.         mCurrentValue = mMinValue;
  408.     else if(value>mMaxValue)
  409.         mCurrentValue = mMaxValue;
  410.     else
  411.         mCurrentValue = value;
  412.     if(mLabel!=0)
  413.         mLabel->setText(QString::number(mCurrentValue),false);
  414.     update();
  415. }
  416. float QcNeedleItem::currentValue()
  417. {
  418.     return mCurrentValue;
  419. }
  420. void QcNeedleItem::setValueFormat(QString format){
  421.     mFormat = format;
  422.     update();
  423. }
  424. QString QcNeedleItem::currentValueFormat(){
  425.     return mFormat;
  426. }
  427. void QcNeedleItem::setColor(const QColor &color)
  428. {
  429.     mColor = color;
  430.     update();
  431. }
  432. QColor QcNeedleItem::color()
  433. {
  434.     return mColor;
  435. }
  436. void QcNeedleItem::setLabel(QcLabelItem *label)
  437. {
  438.     mLabel = label;
  439.     update();
  440. }
  441. QcLabelItem *QcNeedleItem::label()
  442. {
  443.     return mLabel;
  444. }
  445. void QcNeedleItem::setNeedle(QcNeedleItem::NeedleType needleType)
  446. {
  447.     mNeedleType = needleType;
  448.     update();
  449. }
  450. void QcNeedleItem::createDiamonNeedle(float r)
  451. {
  452.     QVector<QPointF> tmpPoints;
  453.     tmpPoints.append(QPointF(0.0, 0.0));
  454.     tmpPoints.append(QPointF(-r/20.0,r/20.0));
  455.     tmpPoints.append(QPointF(0.0, r));
  456.     tmpPoints.append(QPointF(r/20.0,r/20.0));
  457.     mNeedlePoly = tmpPoints;
  458. }
  459. void QcNeedleItem::createTriangleNeedle(float r)
  460. {
  461.     QVector<QPointF> tmpPoints;
  462.     tmpPoints.append(QPointF(0.0, r));
  463.     tmpPoints.append(QPointF(-r/40.0, 0.0));
  464.     tmpPoints.append(QPointF(r/40.0,0.0));
  465.     mNeedlePoly = tmpPoints;
  466. }
  467. void QcNeedleItem::createFeatherNeedle(float r)
  468. {
  469.     QVector<QPointF> tmpPoints;
  470.     tmpPoints.append(QPointF(0.0, r));
  471.     tmpPoints.append(QPointF(-r/40.0, 0.0));
  472.     tmpPoints.append(QPointF(-r/15.0, -r/5.0));
  473.     tmpPoints.append(QPointF(r/15.0,-r/5));
  474.     tmpPoints.append(QPointF(r/40.0,0.0));
  475.     mNeedlePoly = tmpPoints;
  476. }
  477. void QcNeedleItem::createAttitudeNeedle(float r)
  478. {
  479.     QVector<QPointF> tmpPoints;
  480.     tmpPoints.append(QPointF(0.0, r));
  481.     tmpPoints.append(QPointF(-r/20.0, 0.85*r));
  482.     tmpPoints.append(QPointF(r/20.0,0.85*r));
  483.     mNeedlePoly = tmpPoints;
  484. }
  485. void QcNeedleItem::createCompassNeedle(float r)
  486. {
  487.     QVector<QPointF> tmpPoints;
  488.     tmpPoints.append(QPointF(0.0, r));
  489.     tmpPoints.append(QPointF(-r/15.0, 0.0));
  490.     tmpPoints.append(QPointF(0.0, -r));
  491.     tmpPoints.append(QPointF(r/15.0,0.0));
  492.     mNeedlePoly = tmpPoints;
  493. }
复制代码
以上是Qt绘制指南针实当代码,在实际利用中,可以根据需要自定义动画文件和样式。
该自定义控件主要特点有:
1、纯QPaint绘制,不包括图片等文件;
2、多种自定义控制,非常机动;
3、能够自顺应大小,不需要手动调整;
        需要留意的是,在利用QPainter时,需要机动运用QPainter的绘图函数和提供给用户的交互函数,并留意处置惩罚用户的交互操纵和组件的尺寸调整等问题。
五、利用示例

以下是一个简单的示例代码,演示了如何在Qt中利用此控件:
  
  1. #include "mainwindow.h"
  2. #include "compasswidget.h"
  3. #include <QSlider>
  4. #include <QHBoxLayout>
  5. MainWindow::MainWindow(QWidget *parent)
  6.     : QMainWindow(parent)
  7. {
  8.     CompassWidget *pCompassWidget = new CompassWidget(this);
  9.     QSlider *slider = new QSlider(this);
  10.     slider->setRange(0, 360);
  11.     connect(slider, &QSlider::valueChanged, pCompassWidget, &CompassWidget::setCurrentValue);
  12.     QWidget *widget = new QWidget(this);
  13.     QHBoxLayout *layout = new QHBoxLayout(widget);
  14.     layout->addWidget(pCompassWidget);
  15.     layout->addWidget(slider);
  16.     setCentralWidget(widget);
  17.     resize(400, 400);
  18. }
  19. MainWindow::~MainWindow()
  20. {
  21. }
复制代码
总结一下,指南针的计划方法和流程如下:
1、绘制指南针的配景。可以利用QPainter的drawEllipse方法来绘制一个圆形配景,然后填充颜色。
2、绘制指南针的刻度。可以利用QPainter的drawLine方法绘制指南针的刻度线,通过循环来绘制全部的刻度。
3、绘制指南针的指针。可以利用QPainter的drawLine方法绘制指南针的指针线,通过盘算指针的角度来确定其位置。
4、绘制指南针的文字标签。可以利用QPainter的drawText方法绘制文字,并根据指南针的角度来确定文字标签的位置。
六、绘制一个速度表盘 

        我们利用QcGaugeWidget 将CompassWidget内init稍作修改即可实现一个速度仪表盘,代码如下(表盘和指针对象名称已修改):  
  1.     m_pSpeedGauge = new QcGaugeWidget(this);
  2.     m_pSpeedGauge->addBackground(99);
  3.     QcBackgroundItem *bkg1 = m_pSpeedGauge->addBackground(92);
  4.     bkg1->clearrColors();
  5.     bkg1->addColor(0.1,Qt::black);
  6.     bkg1->addColor(1.0,Qt::white);
  7.     QcBackgroundItem *bkg2 = m_pSpeedGauge->addBackground(88);
  8.     bkg2->clearrColors();
  9.     bkg2->addColor(0.1,Qt::gray);
  10.     bkg2->addColor(1.0,Qt::darkGray);
  11.     m_pSpeedGauge->addArc(55);
  12.     m_pSpeedGauge->addDegrees(65)->setValueRange(0,80);
  13.     m_pSpeedGauge->addColorBand(50);
  14.     m_pSpeedGauge->addValues(80)->setValueRange(0,80);
  15.     m_pSpeedGauge->addLabel(70)->setText("Km/h");
  16.     QcLabelItem *lab = m_pSpeedGauge->addLabel(40);
  17.     lab->setText("0");
  18.     m_pSpeedNeedle = m_pSpeedGauge->addNeedle(60);
  19.     m_pSpeedNeedle->setLabel(lab);
  20.     m_pSpeedNeedle->setColor(Qt::white);
  21.     m_pSpeedNeedle->setValueRange(0,80);
  22.     m_pSpeedGauge->addBackground(7);
  23.     m_pSpeedGauge->addGlass(88);
  24.     m_pMainLayout = new QVBoxLayout(this);
  25.     m_pMainLayout->addWidget(m_pSpeedGauge);
  26.     setLayout(m_pMainLayout);
复制代码
结果如下:
 

        谢谢您的关注和阅读。如果您还有其他问题或需要进一步的资助,请随时联系我。祝您一切顺利!
七、源代码下载



免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。
回复

使用道具 举报

0 个回复

倒序浏览

快速回复

您需要登录后才可以回帖 登录 or 立即注册

本版积分规则

河曲智叟

金牌会员
这个人很懒什么都没写!

标签云

快速回复 返回顶部 返回列表