3.7 倒计时计时器——全部代码

全部代码

在这里插入图片描述

#ifndef DIALCLOCK_H
#define DIALCLOCK_H

#include <QWidget>
#include <QPainter>

class DialClock : public QWidget
{
    Q_OBJECT
public:
    explicit DialClock(QWidget *parent = nullptr);

signals:

public slots:
    void SetupClockTime(float aValue);//aValue的值为信号函数传递的值


protected:
    void paintEvent(QPaintEvent *event);

private:
    float m_roateValue;//旋转值

};

#endif // DIALCLOCK_H

在这里插入图片描述

#include "dialclock.h"
#include <QDebug>

#define DIALCLOCK_STARTX 75    //x
#define DIALCLOCK_STARTY 188   //Y
#define DIALCLOCK_WIDTH  285   //宽
#define DIALCLOCK_HEIGHT 285   //高

#define NEEDLE_WIDTH  26 //针的宽
#define NEEDLE_HEIGHT 90 //针的高


DialClock::DialClock(QWidget *parent) : QWidget(parent)
{
    //设置表的位置
    setGeometry(DIALCLOCK_STARTX,DIALCLOCK_STARTY,DIALCLOCK_WIDTH,DIALCLOCK_HEIGHT);
    setStyleSheet("background-color:RGB(0,0,0,0)");

//    setStyleSheet(QString("background-image:url(/images/ImageResources/dial.png);"
//                          "background-repeat:no-repeat;"));

    m_roateValue=0.0;
}

void DialClock::paintEvent(QPaintEvent *event)
{
    Q_UNUSED(event)
    //绘制表盘
    QPainter painter(this);
    painter.setRenderHint(QPainter::Antialiasing);
    painter.setRenderHint(QPainter::SmoothPixmapTransform,true);//做平滑画面处理
    painter.save();
    painter.drawPixmap(rect(),QPixmap(":/images/ImageResources/dial.png"));
    painter.restore();

    //绘制指针
    painter.save();
    painter.translate(width()/2,height()/2);//平移:转换点的坐标为表盘中心点
    painter.rotate(m_roateValue);
    painter.drawPixmap(-13,-80,NEEDLE_WIDTH,NEEDLE_HEIGHT,QPixmap(":/images/ImageResources/needle.png"));
    painter.restore();
}


void DialClock::SetupClockTime(float aValue)//启动表盘槽函数
{
    //qDebug()<<"Clock:"<<aValue;
    m_roateValue=360*aValue;
    repaint();//调用paintEvent()函数
}

在这里插入图片描述

#ifndef RULER_H
#define RULER_H

#include <QWidget>
#include <QPainter>

#include "rulerheader.h"

class RulerHeader;

class Ruler : public QWidget
{
    Q_OBJECT
public:
    explicit Ruler(QWidget *parent = nullptr);
    virtual ~Ruler();

signals:
    void rulerStrechSignal(float value); //拉动时发送的信号
    void rulerDoneSignal(float value);//拉动结束时发送的信号


private:
    RulerHeader *m_rulerHeader;

    QPoint       m_orignalPosistion;//记录最初的位置
    int          m_currentPosY;//记录鼠标当前位置


private  slots:
    void OnRulerHeaderMove(int aValue);
    void OnulerHeaderRelase();



protected:
    void paintEvent(QPaintEvent *event);

public:
    void SetRulerReset();//设置还原
    void UpdateRulerHight(float aValue);
};

#endif // RULER_H

在这里插入图片描述

#include "ruler.h"
#include "rulerheader.h"
#include <QDebug>

//定义宽高,起点和终点
#define RULERWIDGHT_STARTX 351  //定义X坐标
#define RULERWIDGHT_STARTY 100  //定义Y坐标

#define RULER_WIDTH 82          //尺子的宽
#define RULER_HIGHT 574         //尺子的长
#define RULER_MAX_HEIGHT 486    //最大伸长量


Ruler::Ruler(QWidget *parent) : QWidget(parent)
{

    setGeometry(RULERWIDGHT_STARTX,RULERWIDGHT_STARTY,RULER_WIDTH,RULER_HIGHT);
    setStyleSheet("background-color:RGB(0,0,0,0)");

/*               测试                   */
//    setAutoFillBackground(true);//自动填充背景
//     //设置颜色 测试
//    QPalette palette;
//    palette.setBrush(QPalette::Background,Qt::red);
//    setPalette(palette);

    m_rulerHeader=new RulerHeader(this);

    //连接信号与槽
    connect(m_rulerHeader,SIGNAL(RulerHeaderMoveSignal(int)),this,SLOT(OnRulerHeaderMove(int)));//注意信号函数中不写参数
    connect(m_rulerHeader,SIGNAL(RulerHeaderRelaseSignal()),this,SLOT(OnulerHeaderRelase()));

    m_orignalPosistion=m_rulerHeader->pos();//获取开始的位置,和尺子头一个位置
    m_currentPosY=0;

}
Ruler::~Ruler()
{
    if(m_rulerHeader!=NULL)
    {
        delete  m_rulerHeader;
        m_rulerHeader=NULL;
    }

}

//尺子头移动的槽函数
void Ruler::OnRulerHeaderMove(int aValue)
{
    //qDebug()<<"POSY"<<aValue;
    if(m_rulerHeader==NULL)
    {
        return;
    }
    int realPosY=aValue+m_currentPosY;//获取鼠标移动的位置+当前停留的位置
    if((realPosY<=RULER_MAX_HEIGHT) &&(realPosY >= 0))
    {
        m_rulerHeader->move(m_orignalPosistion.rx(),realPosY);//不需要处理x轴
    }

    //表盘的比率=拉伸长度/最大长度
    float dialRation=m_rulerHeader->pos().y()/486.0;
    emit rulerStrechSignal(dialRation);
    repaint();//自动调用painterEvent
}

//尺子头释放(停止移动)的槽函数
void Ruler::OnulerHeaderRelase()
{
    m_currentPosY=m_rulerHeader->pos().ry();
    //表盘的比率=拉伸长度/最大长度
    float dialRation=m_rulerHeader->pos().y()/486.0;
    emit rulerDoneSignal(dialRation);
}






void  Ruler::paintEvent(QPaintEvent *event)
{
    Q_UNUSED(event);
    //event->rect();
    //绘制尺子
    QPainter painter(this);
    painter.setRenderHint(QPainter::Antialiasing);
    painter.save();//保存
    painter.setPen(QPen(QColor(127,159,124),1));
    painter.setBrush(QColor(Qt::red));
    //               x  y  w  h
    painter.drawRect(15,3,52,m_rulerHeader->pos().y());
    painter.restore();//储存 使用save函数必须使用restore


    //数学测试
//     painter.save();//保存
//     painter.setPen(QPen(QColor(255,255,254),10));
//     painter.drawPoint(15,3);
//     painter.drawPoint(52,3);
//     painter.drawPoint(67,3);
//     painter.restore();

    //绘制刻度
    int sScale=5;//短刻度
    int lScale=25;//长刻度
    int CurrentRulerHeight=m_rulerHeader->pos().y();
    //一百米跑道五米画一个点需要多少个点一个道理
    int sScale_count=CurrentRulerHeight/sScale+1;//绘制多少个短刻度
    int lScale_count=CurrentRulerHeight/lScale+1;//绘制多少个长的刻度

    painter.setPen(QPen(QColor(0,0,0),1));

    for(int i=0;i<sScale_count;i++)
    {
        if(i%5!=0)//不是5的倍数,防止和长线重合
        {
            //67=52+15
            //  =w+x
            painter.drawLine(QPoint(67-5,5*i),QPoint(67,5*i));
        }
    }

    for(int i=0;i<lScale_count;i++)
    {
        painter.drawLine(QPoint(67-10,25*i),QPoint(67,25*i));
    }
}

void Ruler::SetRulerReset()
{
    m_rulerHeader->move(m_orignalPosistion.rx(),0);
    m_currentPosY=0;
    repaint();
}


void Ruler::UpdateRulerHight(float aValue)
{
    int currentY=aValue*RULER_MAX_HEIGHT;//秒数/3600 *最大长度==当前的高度
    m_rulerHeader->move(m_orignalPosistion.rx(),currentY);
    repaint();
}

在这里插入图片描述

#ifndef RULERHEADER_H
#define RULERHEADER_H

#include <QWidget>
#include <QMouseEvent>
#include <QPaintEvent>
#include <QPainter>
#include <QPixmap>

#include <QDebug>

class RulerHeader : public QWidget
{
    Q_OBJECT
public:
    explicit RulerHeader(QWidget *parent = nullptr);
    virtual ~RulerHeader();

signals:
    void RulerHeaderMoveSignal(int posY);//鼠标移动信号
    void RulerHeaderRelaseSignal();//鼠标释放的信号

private:
    QPoint last_mouse_position;//记录鼠标位置坐标点


protected:
    void mouseReleaseEvent(QMouseEvent *event);
    void mouseMoveEvent(QMouseEvent *event);
    void mousePressEvent(QMouseEvent *event);

    void paintEvent(QPaintEvent *event);


};

#endif // RULERHEADER_H

在这里插入图片描述

#include "rulerheader.h"
#include <QDebug>

#define RULERHEADER_WIDTH 82
#define RULERHEADER_HEIGHT 91

RulerHeader::RulerHeader(QWidget *parent) : QWidget(parent)
{
    //设置尺子头的位置
     setGeometry(0,0,RULERHEADER_WIDTH,RULERHEADER_HEIGHT);
}
RulerHeader::~RulerHeader()
{

}

//先获取鼠标的位置,鼠标移动产生位移
void RulerHeader::mousePressEvent(QMouseEvent *event)
{
    //记录鼠标左键位置
    if(event->button()==Qt::LeftButton)
    {
        last_mouse_position=event->globalPos();//尺子头的坐标等于鼠标点的坐标
    }
}

void RulerHeader::mouseMoveEvent(QMouseEvent *event)
{
    //记录鼠标左键位置
    if(event->buttons()&Qt::LeftButton)
    {
        QPoint position=event->globalPos()-last_mouse_position;
        emit RulerHeaderMoveSignal(position.y());//返回Y坐标
        //qDebug()<<"mouse "<<position;
    }
}

void RulerHeader::mouseReleaseEvent(QMouseEvent *event)
{
    Q_UNUSED(event);
    emit RulerHeaderRelaseSignal();
}
void RulerHeader::paintEvent(QPaintEvent *event)
{
     //绘制尺子头
    Q_UNUSED(event);//不使用 event 指针
    QPainter painter(this);
    painter.setRenderHint(QPainter::Antialiasing);//设置抗锯齿
    painter.save();
    painter.drawPixmap(rect(),QPixmap(":/images/ImageResources/ruler_head.png"));
    painter.restore();
    //qDebug()<<"绘图完成";
}

在这里插入图片描述

#ifndef WIDGET_H
#define WIDGET_H

#include <QWidget>
#include <QPainter>
#include <QPaintEvent>
#include <QPixmap>
#include <QDesktopWidget>//设置桌面窗口

#include <QLabel>
#include <QTimer>
#include <QPushButton>

#include "ruler.h"
#include "dialclock.h"


QT_BEGIN_NAMESPACE
namespace Ui { class Widget; }
QT_END_NAMESPACE


class Ruler;
class DialClock;


class Widget : public QWidget
{
    Q_OBJECT//使用原对象系统

public:
    Widget(QWidget *parent = nullptr);
    ~Widget();

private:
    Ui::Widget *ui;

public:
    void loadFrontWidget();//加载ruler和ruler header
    QString caculateFormateTimeWithSecond(int aSeconds);//计算文本时间s为格式化的字符串

private:
    Ruler* m_ruler;
    DialClock* m_dialClock;

    QLabel *m_pTimeLabel;
    QTimer *m_pCountDwonTimer;


    int     m_nRulerStettedSecond;//记录鼠标释放时的时间
    QPushButton *m_pPlayButton;
    QPushButton *m_pResetButton;

    bool    m_TimerPlaying;//判断定时器是否在运行



private slots:
    void OnRulerStrechDone(float aValue);//尺子松开时的槽函数
    void OnCountDownTimerProcess();

    void OnPlayButtonClicked();//鼠标点击时的开始按键
    void OnResetButtonClicked();//鼠标重置事件

protected:
    void paintEvent(QPaintEvent *event);


};
#endif // WIDGET_H

在这里插入图片描述

#include "widget.h"
#include "ui_widget.h"
#include "ruler.h"
#include "dialclock.h"
#include <QFont>
#define  WITDH 433
#define  HEIGHT 755

#define TOOLBUTTON_WIDTH 100
#define TOOLBUTTON_HEIGHT 100

Widget::Widget(QWidget *parent)
    : QWidget(parent)
    , ui(new Ui::Widget)
{
    ui->setupUi(this);
    setWindowFlags(windowFlags() & ~Qt::WindowMinMaxButtonsHint);//去除最大最小化按钮
    setMinimumSize(WITDH,HEIGHT);//设置窗口的最小值
    setMaximumSize(WITDH,HEIGHT);//设置窗口最大值
    setAutoFillBackground(true);//设置窗口填充
    //setAttribute(Qt::WA_TranslucentBackground);//设置透明窗体


    //设置窗口居中
    QDesktopWidget* desktop=QApplication::desktop();//获取桌面窗口
    int startX=(desktop->width()-WITDH)/2;
    int startY=(desktop->height()-HEIGHT)/2;
    setGeometry(startX,startY,WITDH,HEIGHT);

    //加载
    loadFrontWidget();

    m_pCountDwonTimer=new QTimer(this);

    m_nRulerStettedSecond=0;
    connect(m_pCountDwonTimer,SIGNAL(timeout()),this,SLOT(OnCountDownTimerProcess()));



//    connect(m_pCountDwonTimer,&QTimer::timeout,[=](){

//        //计时器计时过程
//        if(m_nRulerStettedSecond<=0)//调用按钮重置
//        {
//            OnResetButtonClicked();
//        }

//        QString formateTime=caculateFormateTimeWithSecond(m_nRulerStettedSecond);
//        m_pTimeLabel->setText(formateTime);
//        //当时间变大时尺子高度会变短
//        float currentRatio=m_nRulerStettedSecond/3600.0;//秒数/3600
//        m_ruler->UpdateRulerHight(currentRatio);
//        m_nRulerStettedSecond--;
//    });


}

Widget::~Widget()
{
    delete ui;
}




void Widget::loadFrontWidget()
{

    m_ruler=new Ruler(this);
    m_dialClock=new DialClock(this);

    //尺子拉动时的连接
    connect(m_ruler,SIGNAL(rulerStrechSignal(float)),m_dialClock,SLOT(SetupClockTime(float)));

    //尺子拉动后
    connect(m_ruler,SIGNAL(rulerDoneSignal(float)),this,SLOT(OnRulerStrechDone(float)));


    //设置字体
    QFont font;
    font.setFamily("PingFang TC");//字体
    font.setWeight(25);//权重
    font.setPixelSize(35);//大小

    m_pTimeLabel=new QLabel(this);
    m_pTimeLabel->setGeometry(138,525,160,60);
    m_pTimeLabel->setFont(font);
    m_pTimeLabel->setStyleSheet("background:transparent;color:#d16b5d");
    m_pTimeLabel->setAlignment(Qt::AlignCenter);//设置对其方式
    m_pTimeLabel->setText("00:00");



    //设置按钮
    m_pPlayButton=new QPushButton(this);
    m_pPlayButton->setGeometry(111,630,TOOLBUTTON_WIDTH,TOOLBUTTON_HEIGHT);
    m_pPlayButton->setIcon(QIcon(":/images/ImageResources/play.png"));
    m_pPlayButton->setIconSize(QSize(TOOLBUTTON_WIDTH,TOOLBUTTON_HEIGHT));
    m_pPlayButton->setAutoFillBackground(true);//设置填充边框
    m_pPlayButton->setFlat(true);//去除按键边框、按钮和背景融为一体
    m_pPlayButton->setStyleSheet("QPushButton{background:transparent}");//设置边框背景色
    m_TimerPlaying=false;


    connect(m_pPlayButton,SIGNAL(clicked(bool)),this,SLOT(OnPlayButtonClicked()));

    m_pResetButton=new QPushButton(this);
    m_pResetButton->setGeometry(251,630,TOOLBUTTON_WIDTH,TOOLBUTTON_HEIGHT);
    m_pResetButton->setIcon(QIcon(":/images/ImageResources/reset.png"));
    m_pResetButton->setIconSize(QSize(TOOLBUTTON_WIDTH,TOOLBUTTON_HEIGHT));
    m_pResetButton->setAutoFillBackground(true);//设置填充边框
    m_pResetButton->setFlat(true);//去除按键边框、按钮和背景融为一体
    m_pResetButton->setStyleSheet("QPushButton{background:transparent}");//设置边框背景色

//    connect(m_pResetButton,&QPushButton::clicked,[=](){
//        //重置按钮
//        if(m_TimerPlaying==true)
//        {
//            if(m_pCountDwonTimer->isActive())
//            {
//                m_pCountDwonTimer->stop();
//            }
//        }

//       m_pPlayButton->setIcon(QIcon(":/images/ImageResources/play.png"));
//       m_TimerPlaying=false;

//       m_nRulerStettedSecond=0;
//       m_pTimeLabel->setText("00:00");
//       m_dialClock->SetupClockTime(0.0);//设置槽函数的传递值为0
//       m_ruler->SetRulerReset();//调动尺子还原的函数


//    });

    connect(m_pResetButton,SIGNAL(clicked(bool)),this,SLOT(OnResetButtonClicked()));

}

void Widget::OnRulerStrechDone(float aValue)//拉伸释放
{
    int mSeconds=(int)3600 * aValue;//3600s*表盘比率
    QString formateTime=caculateFormateTimeWithSecond(mSeconds);
    m_pTimeLabel->setText(formateTime);

    m_nRulerStettedSecond=mSeconds;
    if(m_pCountDwonTimer->isActive())//如果正在计时停止,否在开启
    {
        m_pCountDwonTimer->stop();
    }
    m_pCountDwonTimer->start(100);
}

//计算文本框里的时间
QString Widget::caculateFormateTimeWithSecond(int aSeconds)
{
     int tMinutes=aSeconds/60;//计算多少分钟
     int tSeconds=aSeconds-tMinutes*60;//剩余多少秒

     QString strMinutes=QString("%1").arg(tMinutes);//转换为字符串
     QString strSeconds=QString("%1").arg(tSeconds);


     if((tMinutes<10)&&(tMinutes>=0))//例如09
     {
         strMinutes=QString("0%1").arg(tMinutes);
     }
     if(tSeconds<10&&tSeconds>0)
     {

         strSeconds=QString("0%1").arg(tSeconds);
     }
     //拼接字符串
     QString formateTime=QString("%1:%2").arg(tMinutes).arg(tSeconds);
     return formateTime;
}



void Widget::OnCountDownTimerProcess()
{
    //计时器计时过程
    if(m_nRulerStettedSecond<=0)//调用按钮重置
    {
        OnResetButtonClicked();
    }

    QString formateTime=caculateFormateTimeWithSecond(m_nRulerStettedSecond);
    m_pTimeLabel->setText(formateTime);
    //当时间变大时尺子高度会变短
    float currentRatio=m_nRulerStettedSecond/3600.0;//秒数/3600
    m_ruler->UpdateRulerHight(currentRatio);
    m_nRulerStettedSecond--;
 }



void  Widget::OnPlayButtonClicked()
{
    if(m_TimerPlaying==true)//判断是否在运行,如果在运行就暂停,没有在运行就让定时器开始
    {
        if(m_pCountDwonTimer->isActive())
        {
            m_pCountDwonTimer->stop();
            m_TimerPlaying=false;
        }
        m_pResetButton->setIcon(QIcon(":/images/ImageResources/reset.png"));
    }
    else{
        m_pCountDwonTimer->start(1000);
        m_TimerPlaying=true;
        m_pPlayButton->setIcon(QIcon(":/images/ImageResources/pause.png"));
    }
}

void Widget::OnResetButtonClicked()
{
    //重置按钮
    if(m_TimerPlaying==true)
    {
        if(m_pCountDwonTimer->isActive())
        {
            m_pCountDwonTimer->stop();
        }
    }

   m_pPlayButton->setIcon(QIcon(":/images/ImageResources/play.png"));
   m_TimerPlaying=false;

   m_nRulerStettedSecond=0;
   m_pTimeLabel->setText("00:00");
   m_dialClock->SetupClockTime(0.0);//设置槽函数的传递值为0
   m_ruler->SetRulerReset();//调动尺子还原的槽函数
}


//绘制窗口背景
void Widget::paintEvent(QPaintEvent *event)
{
    Q_UNUSED(event);//没有使用event
    QPainter painter(this);
    painter.save();//保存
    painter.setRenderHint(QPainter::Antialiasing,true);//设置反走样,抗锯齿
    painter.drawPixmap(rect(),QPixmap(":/images/ImageResources/background.png"));//rect()当前窗口
    painter.restore();//回复当前状态 save()必须后跟相应的restore()函数

}

在这里插入图片描述

  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值