QT—class3 绘制时钟(电子+钟表)附代码

绘制时钟(电子+钟表)

前言

确实参考了很多资料才做出来,我尽量把那些资料没有说明详细的地方补充完整~

一、效果展示

大致是这样的效果~喜欢看球,所以选了利指导的读表时刻 ~
不是很精致~
在这里插入图片描述

二、绘制时针、分针、秒针

逐步解读
  • QTime time=QTime::currentTime()
    返回系统时钟报告的当前时间。

  • painter->save();
    { }
    painter->restore();
    QPainter是一个状态机。那么,有时我想保存下当前的状态:当我临时绘制某些图像时,就可能想这么做。当然,我们有最原始的办法:将可能改变的状态,比如画笔颜色、粗细等,在临时绘制结束之后再全部恢复。对此,QPainter提供了内置的函数:save()和restore()。save()就是保存下当前状态;restore()则恢复上一次保存的结果。这两个函数必须成对出现:QPainter使用栈来保存数据,每一次save(),将当前状态压入栈顶,restore()则弹出栈顶进行恢复。

  • painter->rotate(度数)。

  • painter->drawConvexPolygon()画指针的函数,这里是画一个多边形指针。一开始得构建几个点来绘图,我试了下,感觉参数都不重要,随便几个点甚至点的个数都可以不确定,就只有些许粗细长短之分。

const QPoint Widget::hourhand[4]={
     QPoint(5,5),QPoint(0,13),QPoint(-5,5),QPoint(0,-40)
};
const QPoint Widget::minutehand[4]={
     QPoint(3,5),QPoint(0,16),QPoint(-3,5),QPoint(0,-70)
};
const QPoint Widget::secondhand[4]={
     QPoint(0,0),QPoint(0,0),QPoint(0,0),QPoint(0,0)
};
  • painter.setRenderHint(QPainter::Antialiasing,true);这是个反走样的函数,就去指针的边缘化。我也不是很懂~。
    *这个部分找了很多资料才理解,看帮助也不是太懂哈~ painter.setWindow(rect())就是选择要放大的区域原本是多大。
  • painter.setViewport(96,0,side,side);//映射到新的区域面积多大
    painter.setWindow(0,0,230,230);//原本截取放大的面积区域多大
    painter.setViewport(96,0,side,side);//映射到新的区域面积多大
  • 因为原本圆心部位画的图只能展示出一部分,要把圆心重新设置
 painter.translate(100,100);;//重新设定坐标原点
  • 这部分主要代码

void Widget::drawhourhand(QPainter*painter)
{
    QTime time=QTime::currentTime();
    painter->setBrush(Qt::blue);//画刷,填充
    painter->setPen(Qt::Dense7Pattern);//画笔,制作廓线
    painter->save();
    painter->rotate(30.0*(time.hour()+time.minute()/60));//使得指针旋转到当前时间位置
    painter->drawConvexPolygon(hourhand,4);;//绘制时针(凸多边形)
    painter->restore();//与save连着用 绘制图形后复位坐标系
}
void Widget::drawminutehand(QPainter*painter)
{
    QTime time=QTime::currentTime();
    painter->setBrush(Qt::white);
    painter->setPen(Qt::Dense5Pattern);
    painter->save();
    painter->rotate(6.0*(time.minute()+time.second()/60.0));
    painter->drawConvexPolygon(minutehand,4);
    painter->restore();
}
void Widget::drawsecondhand(QPainter*painter)
{
    QTime time=QTime::currentTime();
    painter->setBrush(Qt::red);
    painter->setPen(Qt::Dense5Pattern);
    painter->save();
    painter->rotate(6*time.second());
    painter->drawPolygon(minutehand,4);
    painter->restore();
}

三、绘制表盘

逐步解读
  • 一开始先设置QPen 两个笔一个笔专门来画每小时的大粗线,另一个画细线。
  • Qt::AlignHCenter|Qt::AlignTop 文字位置,正底下。
  • 同样要save 和restore保存恢复
  • 主要代码
void Widget::drawclockdial(QPainter*painter)
{
    hourhandpen.setColor(Qt::white);
    hourhandpen.setWidth(2.0);//设置小时刻度线为粗黑
    minutehandpen.setColor(Qt::white);
    for(int i=1;i<=60;i++)
    {
        painter->save();
        painter->rotate(6*i);
        if(i%5==0)
        {
            painter->setPen(hourhandpen);
            painter->drawLine(0,-98,0,-82);
            painter->drawText(-20,-82,40,40,Qt::AlignHCenter|Qt::AlignTop,QString::number(i/5));
        }
        else
        {
            painter->setPen(minutehandpen);
            painter->drawLine(0,-98,0,-88);
        }
        painter->restore();
    }
}

三、绘制电子时钟

*实现代码

 QString timeStr= QTime::currentTime().toString();     //绘制当前的电子时间
    painter.setPen(Qt::white);
    painter.drawText(-20,30,80,30,0,timeStr);

四、实现界面刷新(时间走动)

*信号槽机制

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

五、字体设置

  • 稍微提一下这个QFont头文件专门设置字体的
    font.setPixelSize(10);
    setFont(font);

五、易错点归纳

  • QTimer 和 QTime两个头文件一个是时钟触发器用来刷新界面使得指针转动,另一个是获取系统时间的头文件
  • 要先确立放大区域和重新确定原点再来以此为基础绘制。
#include "widget.h"
#include "ui_widget.h"


Widget::Widget(QWidget *parent) :
    QWidget(parent),
    ui(new Ui::Widget)
{
    ui->setupUi(this);
    font.setPixelSize(10);
    setFont(font);
    setWindowTitle("THE CLOCK");
    resize(1200,820);
}


Widget::~Widget()
{
    delete ui;
}
const QPoint Widget::hourhand[4]={
     QPoint(5,5),QPoint(0,13),QPoint(-5,5),QPoint(0,-40)
};
const QPoint Widget::minutehand[4]={
     QPoint(3,5),QPoint(0,16),QPoint(-3,5),QPoint(0,-70)
};
const QPoint Widget::secondhand[4]={
     QPoint(0,0),QPoint(0,0),QPoint(0,0),QPoint(0,0)
};
void Widget::drawhourhand(QPainter*painter)
{
    QTime time=QTime::currentTime();
    painter->setBrush(Qt::blue);//画刷,填充
    painter->setPen(Qt::Dense7Pattern);//画笔,制作廓线
    painter->save();
    painter->rotate(30.0*(time.hour()+time.minute()/60));//使得指针旋转到当前时间位置
    painter->drawConvexPolygon(hourhand,4);;//绘制时针(凸多边形)
    painter->restore();//与save连着用 绘制图形后复位坐标系
}
void Widget::drawminutehand(QPainter*painter)
{
    QTime time=QTime::currentTime();
    painter->setBrush(Qt::white);
    painter->setPen(Qt::Dense5Pattern);
    painter->save();
    painter->rotate(6.0*(time.minute()+time.second()/60.0));
    painter->drawConvexPolygon(minutehand,4);
    painter->restore();
}
void Widget::drawsecondhand(QPainter*painter)
{
    QTime time=QTime::currentTime();
    painter->setBrush(Qt::red);
    painter->setPen(Qt::Dense5Pattern);
    painter->save();
    painter->rotate(6.0*time.second());
    painter->drawPolygon(minutehand,4);
    painter->restore();
}
void Widget::paintEvent(QPaintEvent*event)
{
    QPainter painter(this);
    QTimer*timer=new QTimer(this);
    timer->start(1000);
    connect(timer,SIGNAL(timeout()),this,SLOT(update()));
    QPixmap map(":/new/prefix1/timg (1).jfif");
    QRect q(0,0,1200,800);//截取这么大的面积
    QRect q2(0,0,width(),height());//放到指定大小的框中
    painter.drawPixmap(q2,map,q);
    painter.setRenderHint(QPainter::Antialiasing,true);//反走样
    int side=qMin(width(),height());
    painter.setWindow(0,0,230,230);//原本截取放大的面积区域多大
    painter.setViewport(96,0,side,side);//映射到新的区域面积多大
    painter.translate(100,100);//重新设定坐标原点
    drawhourhand(&painter);
    drawminutehand(&painter);
    drawsecondhand(&painter);
    drawclockdial(&painter);
    QString timeStr= QTime::currentTime().toString();     //绘制当前的电子时间
    painter.setPen(Qt::white);
    painter.drawText(-20,30,80,30,0,timeStr);
    painter.setBrush(Qt::black);
    painter.drawEllipse(QPoint(0,0),3,3);//中间画个小圆点
   // QTransform Transform;
   // Transform.rotate(90);
   // painter.setTransform(Transform);
    painter.drawText(-53,-30,QStringLiteral("老子利指导,杀人先看表"));
}
void Widget::drawclockdial(QPainter*painter)
{
    hourhandpen.setColor(Qt::white);
    hourhandpen.setWidth(2.0);//设置小时刻度线为粗黑
    minutehandpen.setColor(Qt::white);
    for(int i=1;i<=60;i++)
    {
        painter->save();
        painter->rotate(6*i);
        if(i%5==0)
        {
            painter->setPen(hourhandpen);
            painter->drawLine(0,-98,0,-82);//原点变了
            painter->drawText(-20,-82,40,40,Qt::AlignHCenter|Qt::AlignTop,QString::number(i/5));
        }
        else
        {
            painter->setPen(minutehandpen);
            painter->drawLine(0,-98,0,-88);
        }
        painter->restore();
    }
}

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值