Loading...
墨滴

阿姝shu

2021/05/12  阅读:35  主题:前端之巅同款

Qt之QPainter绘制时钟

本示例将用QPainter绘画钟表,并用定时器的方式让钟表跑起来。本文还会讲解QPainter帮助文档的使用,通过查询帮助文档来绘制窗口部件。

时钟设计

QPainter()主要提供在窗体或者其他绘图设备上进行绘图的功能,一般在paintEvent事件函数中去使用。它常用函数有:

  • drawXXX()函数,用于绘制图形、文字和路径等;
  • fillXXX()函数,用于填充,可在指定区域内进行填充;
  • brush()和pen(),笔刷和钢笔的相关操作

而paintEvent(QPaintEvent*)函数是QWidget类中的虚函数,可用于ui的绘制。我们可以通过重定义paintEvent函数的方式绘制时钟。

时钟指针

首先在.h头文件类定义中重定义paintEvent。

protected:
    void paintEvent(QPaintEvent *);

首先来画指针。此时对QPainter不熟悉的同学来说,可以借助QPainter的帮助文档来画出指针。 在头文件中#include < QPainter>引入QPainter头文件,鼠标放在QPainter上键盘F1进入帮助文档,可以看到有关QPainter的描述,我们想画指针,所以点击Detailed Description下的Drawing。 此时可以看到有关Drawing的简单描述,发现可以用drawConvexPolygon()画多边形的方式画指针,点击drawConvexPolygon(),进入drawConvexPolygon()函数详细说明。 在drawConvexPolygon()函数说明中,我们可以参考示例代码画出指针。 针对不同的页面大小的情况下,可以考虑对画面缩放和平移,与上述的一样进入帮助文档,在Coordinate Transformations下得知,可利用translate()与scale()对图像进行平移和缩放,利用rotate()旋转指针。 代码如下:

int my_centre=qMin(width(),height())/2;
int my_scale=qMin(width(),height())/150;

painter.translate(my_centre,my_centre);
painter.scale(my_scale,my_scale);

利用QTime::currentTime()得知当前时间,用painter.rotate()扭转指针的角度

painter.rotate((time.hour()*30)+(30*(time.minute()/60.0)));

利用painter.setBrush对指针颜色填充,此时编译运行会发现指针线条并不平滑,会有小锯齿,加入如下代码,防止线条走样。

painter.setRenderHints(QPainter::Antialiasing,true);

时钟表盘

接下来制作表盘,同样可以通过帮助文档画出表盘,整点采用painter.drawText()方式,分钟采用painter.drawLine()方式。 制作好表盘后,时钟就做好了,来看下效果:

加入定时器,让时钟跑起来

最后来加入定时器,让paintEvent每秒重绘一次。这里槽函数调用update()函数,update()函数可以自动调用paintEvent函数,并且当它用于重绘窗口部件时可以让Qt优化速度和减少闪烁。

QTimer *timer = new QTimer(this);
connect(timer, SIGNAL(timeout()), this, SLOT(update()));
timer->start(1);

此时就可以看到时钟在走啦~~

代码

最后附上paintEvent(QPaintEvent*)函数完整代码:

void myclock::paintEvent(QPaintEvent *)
{
     QColor hour_Color(127, 0, 127);
     QColor min_Color(0, 127, 127);
     QColor second_Color(127, 127, 0);

     static const QPointF hour_point[7] = {
          QPointF(0, -28),
          QPointF(-3, -24),
          QPointF(-1, -24),
          QPointF(-1, 0),
          QPointF(1, 0),
          QPointF(1, -24),
          QPointF(3, -24),
      };

     static const QPointF min_points[7] = {
            QPointF(0, -36),
            QPointF(-3, -32),
            QPointF(-1, -32),
            QPointF(-1, 0),
            QPointF(1, 0),
            QPointF(1, -32),
            QPointF(3, -32),
      };

     static const QPointF second_points[7] = {
            QPointF(0, -43),
            QPointF(-3, -39),
            QPointF(-1, -39),
            QPointF(-1, 0),
            QPointF(1, 0),
            QPointF(1, -39),
            QPointF(3, -39),
      };

      QPainter painter(this);

      int my_centre=qMin(width(),height())/2;
      int my_scale=qMin(width(),height())/150;

      painter.translate(my_centre,my_centre);
      painter.scale(my_scale,my_scale);
      painter.setRenderHints(QPainter::Antialiasing,true);
      painter.setPen(Qt::NoPen);

      QTime time=QTime::currentTime();
      painter.save();
      painter.setBrush(hour_Color);
      painter.rotate((time.hour()*30)+(30*(time.minute()/60.0)));
      painter.drawConvexPolygon(hour_point, 7);
      painter.restore();

      painter.save();
      painter.setBrush(min_Color);
      painter.rotate((time.minute()*6)+(6*(time.second()/60.0)));
      painter.drawConvexPolygon(min_points, 7);
      painter.restore();
      
      painter.save();
      painter.setBrush(second_Color);
      painter.rotate(time.second()*6);
      painter.drawConvexPolygon(second_points, 7);
      painter.restore();

      for (int num = 1; num< 13; num++)
      {
             painter.rotate(30);

             QFont myFont;
             myFont.setPointSize(6);
             myFont.setFamily("楷体");
             myFont.setBold(true);
             myFont.setLetterSpacing(QFont::AbsoluteSpacing,-1);
             painter.setFont(myFont);

             QPen hour_pen;
             hour_pen.setColor(hour_Color);
             painter.setPen(hour_pen);

             if(num<10)
             {
                 QPointF baseline(-2, -51);
                 painter.drawText(baseline,QString(QString::number(num)));
             }
             else
             {
                 QPointF baseline(-4, -51);
                 painter.drawText(baseline,QString(QString::number(num)));
             }

       }
       
       for (int j = 0; j < 60; ++j)
       {
             if(j%5!=0)
             {
                     QPen min_pen;
                     min_pen.setColor(min_Color);
                     min_pen.setStyle(Qt::SolidLine);
                     painter.setPen(min_pen);
                     painter.drawLine(0,-54,0,-52);
             }
             painter.rotate(6);

       }

      painter.setPen(Qt::NoPen);
      painter.setBrush(Qt::black);
      painter.drawEllipse(-1,-1,2,2);

}

扫码关注我吧


阿姝shu

2021/05/12  阅读:35  主题:前端之巅同款

作者介绍

阿姝shu