• 从无到有的基于QT软件的DIY桌面番茄钟(上)


    前言

    番茄工作法是个不错的方法,本想要从淘宝买一个番茄钟,但发现要99块钱,太贵了。尝试自制一个基于Windows的桌面悬浮番茄钟。

    经过一番搜索,决定采用Qt方式进行DIY。计划用一周的时间进行DIY,并给出具体的实现细节。

    参考本教程(上篇)可实现的功能:

    • 计时器功能及界面变色功能:番茄钟25min(红色),休息5min(绿色)。
      1
    • 暂停功能:单击实现暂停与恢复暂停。

    12

    • 置顶功能,始终置于其它窗体上面,避免被遮挡。

    后续更多功能及扩展将在**从无到有的基于QT软件的DIY桌面番茄钟(2)**中添加。具体可执行文件将在功能完全扩展后发出,需要目前的beta版本的可执行文件可在评论区留言。

    实现细节:

    Day 1:

    需求导图:

    请添加图片描述

    QT的安装:

    QT官网
    首先从Qt官网下载开源安装包,之后进行安装:
    需要首先进行注册登录,之后进入到如下步骤
    1

    选择如下安装即可,
    在这里插入图片描述

    进入到下载页面,静静等待,
    在这里插入图片描述

    Day 2:

    创建项目:

    1
    1

    1

    创建完后如下:
    在这里插入图片描述
    创建完成后,有如下文件

    • Header Files
      • tomatoclock.h
    • Source Files
      • main.cpp
      • tomatoclock.cpp

    Header Files: 用于放头文件,所有.h的声明都放在这里。
    Source Files: 放源文件,所有.c,.cpp的程序实现的代码都放这里。
    Resource Files: 所有的资源文件,如图标,图片,菜单,文字之类的文件都放这里。

    头文件(header files)又称作预编译文件,是用户应用程序和函数库之间的桥梁和纽带。作为一种包含功能函数、数据接口声明的载体文件,用于保存程序的声明,而定义文件用于保存程序的实现。

    头文件的主要作用在于调用库功能,对各个被调用函数给出一个描述,其本身不包含程序的逻辑实现代码,它只起描述性作用,告诉应用程序通过相应途径寻找相应功能函数的真正逻辑实现代码。用户程序只需要按照头文件中的接口声明来调用库功能,编译器会从库中提取相应的代码。

    简单的说,头文件就是作者告诉程序从哪调用库函数的文件。

    构建无边框界面(后续可添加缩放功能,未添加)

    构建了一个无边框的界面,增加番茄钟的美观图,如图所示:

    1

    增加透明度界面,新增单击界面改变界面透明度(后续统计第几个番茄钟决定用透明度来统计)

    1

    代码展示:

    tomatoclock.h

    #ifndef TOMATOCLOCK_H
    #define TOMATOCLOCK_H
    
    #include 
    #include 
    #include 
    #include 
    QT_BEGIN_NAMESPACE
    namespace Ui { class TomatoClock; }
    QT_END_NAMESPACE
    
    class TomatoClock : public QWidget
    {
        Q_OBJECT
    
    public:
        TomatoClock(QWidget *parent = nullptr);
        ~TomatoClock();
    protected:
    //     声明一些函数
        void mousePressEvent(QMouseEvent *e); //鼠标单击事件
        void mouseMoveEvent(QMouseEvent *e); // 鼠标单击拖动窗口
    private:
        int boundaryWidth;
        float Opacity;
        QPoint clickPos;
        Ui::TomatoClock *ui;
    };
    #endif // TOMATOCLOCK_H
    
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31

    main.cpp

    #include "tomatoclock.h"
    
    #include 
    
    int main(int argc, char *argv[])
    {
        QApplication a(argc, argv);
        TomatoClock w;
        w.show();
        return a.exec();
    }
    
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13

    tomatoclock.cpp

    #include "tomatoclock.h"
    #include "./ui_tomatoclock.h"
    
    TomatoClock::TomatoClock(QWidget *parent)
        : QWidget(parent)
        , ui(new Ui::TomatoClock)
    {
        ui->setupUi(this);
        boundaryWidth=4;                                    //设置触发resize的宽度
        Opacity = 1.0;
        this->setWindowFlags(Qt::FramelessWindowHint);      //设置为无边框窗口
        this->setMinimumSize(45,45);                        //设置最小尺寸
        this->setStyleSheet("background:#D1EEEE");          //设置背景颜色
        this->setWindowOpacity(Opacity);                    //设置不透明度
    
    }
    TomatoClock::~TomatoClock()
    {
        delete ui;
    }
    
    
    
    void TomatoClock::mousePressEvent(QMouseEvent *e)
    {
        if(e->button()==Qt::LeftButton)
            clickPos=e->pos();
            Opacity = 0.5;
            this->setWindowOpacity(Opacity);
    }
    void TomatoClock::mouseMoveEvent(QMouseEvent *e)
    {
        if(e->buttons()&Qt::LeftButton)
            move(e->pos()+pos()-clickPos); //父窗口的左上角+当前鼠标指针移动-初始单击时候鼠标指针的方向
    }
    
    
    //void move(const QPoint &);
    //其中move的原点是父窗口的左上角,  如果没有父窗口,则桌面即为父窗口
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40

    Day 3:

    计时器的实现

    • 实现计时器功能及计时器初始化以及暂停功能。通过单击窗体实现暂停及恢复暂停。
    • 增加一些界面美化功能,包括单击窗体界面变色以及番茄钟期间和休息期间界面不同颜色。
    • 增加置顶功能,始终置于其它窗体上面,避免被遮挡。

    具体示例参考Gif图:

    • 计时器功能及界面变色功能:
      1
    • 暂停功能:
    • 12

    参考代码:

    tomatoclock.h

    #ifndef TOMATOCLOCK_H
    #define TOMATOCLOCK_H
    
    #include 
    #include 
    #include 
    #include 
    #include 
    #include 
    QT_BEGIN_NAMESPACE
    namespace Ui { class TomatoClock; }
    QT_END_NAMESPACE
    
    class TomatoClock : public QWidget
    {
        Q_OBJECT
    
    public:
        TomatoClock(QWidget *parent = nullptr);
        ~TomatoClock();
    
    protected:
    //     声明一些函数
        void mousePressEvent(QMouseEvent *e); //鼠标单击事件
        void mouseMoveEvent(QMouseEvent *e); // 鼠标单击拖动窗口
    
    private slots:
        void initTime(); //初始化时间
        void updateTime(); //更新时间
    private:
        float Opacity; //透明度控制
        int state; //用于暂停和恢复暂停
        int tomato_num; //番茄钟计数
        QString current_color;
        QPoint clickPos;
        Ui::TomatoClock *ui;
        QTimer *timer;
        QTime time;
    
    };
    #endif // TOMATOCLOCK_H
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42

    main.cpp

    #include "tomatoclock.h"
    
    #include 
    
    int main(int argc, char *argv[])
    {
        QApplication a(argc, argv);
        TomatoClock w;
        w.show();
        return a.exec();
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12

    tomatoclock.cpp

    #include "tomatoclock.h"
    #include "./ui_tomatoclock.h"
    
    TomatoClock::TomatoClock(QWidget *parent)
        : QWidget(parent)
        , ui(new Ui::TomatoClock)
    {
        ui->setupUi(this);
        Opacity = 0.8; // 透明度设置
        state = 1;   // 暂停,恢复暂停
        tomato_num = 0; //番茄钟计数
        current_color = "background:#CD9B9B"; //当前背景色设置
        this->setStyleSheet(current_color);                 //设置背景颜色
        this->setWindowFlags(Qt::FramelessWindowHint);      //设置为无边框窗口
    //    this->setMinimumSize(100,50);                        //设置最小尺寸
    //    this->setMaximumSize(200,100);                      //设置最大尺寸
        this->setWindowOpacity(Opacity);                    //设置不透明度
        // 置顶
        ::SetWindowPos(HWND(this->winId()), HWND_TOPMOST, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE | SWP_SHOWWINDOW);
    //    // 不置顶
    //    ::SetWindowPos(HWND(this->winId()), HWND_NOTOPMOST, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE | SWP_SHOWWINDOW);
    
        timer = new QTimer;
    
        ui->Timer->setDigitCount(5);                    //设置显示位数为8位
        initTime();                                      //令LCD显示00:00:00
        timer->setInterval(1000);                        //设置定时器间隔为1000=1s
        //连接槽函数,将timer的timeout行为,连接到updateTime函数中
        connect(timer, SIGNAL(timeout()), this, SLOT(updateTime()));
        //当点击(clicked)pbStart时,调用函数pbStart_clicked
        //connect(ui->pbStart, SIGNAL(clicked()), this, SLOT(pbStart_clicked()));
        timer->start();  //启用定时器
    
    
    }
    TomatoClock::~TomatoClock()
    {
        delete ui;
    }
    
    
    
    void TomatoClock::mousePressEvent(QMouseEvent *e)  //鼠标单击事件
    {
        if(e->button()==Qt::LeftButton)
            clickPos=e->pos();
    
            this->setWindowOpacity(Opacity);
            if (state == 1){
                //暂停
                state = 0;
                this->setStyleSheet("background:#B5B5B5");    //设置暂停背景颜色
                Opacity = 0.2;
                timer->stop();
                this->setWindowOpacity(Opacity);                    //设置不透明度
            }else{//恢复
                state = 1;
                timer->start();
                this->setStyleSheet( current_color);          //恢复背景颜色
                Opacity = 0.8;
            }
            this->setWindowOpacity(Opacity);                    //设置不透明度
    }
    void TomatoClock::mouseMoveEvent(QMouseEvent *e)  //鼠标移动事件
    {
        if(e->buttons()&Qt::LeftButton)
            move(e->pos()+pos()-clickPos); //父窗口的左上角+当前鼠标指针移动-初始单击时候鼠标指针的方向
    }
    
    //void move(const QPoint &);
    //其中move的原点是父窗口的左上角,  如果没有父窗口,则桌面即为父窗口
    
    
    void TomatoClock::initTime()
    {
        time.setHMS(0,0,0); //时间复位 0
        ui->Timer->display(time.toString("mm:ss"));
    }
    
    void TomatoClock::updateTime()
    {
        //每次更新时间,time增加1
        time = time.addSecs(1);
        ui->Timer->display(time.toString("mm:ss"));
        if (time.minute() == 5 and tomato_num==1){
            //休息完毕,进入番茄钟
            tomato_num = 0;
            initTime();
            current_color = "background:#CD9B9B";
            this->setStyleSheet(current_color);    //进入番茄色
        }else if(time.minute() == 25){
            //番茄钟完毕,进入休息时间
            tomato_num = 1;
            initTime();
            current_color = "background:#9BCD9B";
            this->setStyleSheet(current_color);    //进入休息色
        }
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69
    • 70
    • 71
    • 72
    • 73
    • 74
    • 75
    • 76
    • 77
    • 78
    • 79
    • 80
    • 81
    • 82
    • 83
    • 84
    • 85
    • 86
    • 87
    • 88
    • 89
    • 90
    • 91
    • 92
    • 93
    • 94
    • 95
    • 96
    • 97
    • 98
    • 99

    tomatoclock.ui

    
    <ui version="4.0">
     <class>TomatoClockclass>
     <widget class="QWidget" name="TomatoClock">
      <property name="enabled">
       <bool>truebool>
      property>
      <property name="geometry">
       <rect>
        <x>0x>
        <y>0y>
        <width>211width>
        <height>101height>
       rect>
      property>
      <property name="windowTitle">
       <string>TomatoClockstring>
      property>
      <widget class="QLCDNumber" name="Timer">
       <property name="geometry">
        <rect>
         <x>20x>
         <y>10y>
         <width>171width>
         <height>81height>
        rect>
       property>
      widget>
     widget>
     <resources/>
     <connections/>
    ui>
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33

    具体ui窗体设计(注意命名的变化):
    1

  • 相关阅读:
    C++多态之虚函数表详解及代码示例
    利用 SOAR 加快事件响应并加强网络安全
    Linux文件权限管理:chomd命令和chown命令
    Kafka内外网分流配置listeners和advertised.listeners
    从零到一搭建基础架构(4)-base模块搭建下篇
    链表简单功能的总结
    LT6911C是HDMI1.4转双MIPIDSI/CSI带音频
    [ vulhub漏洞复现篇 ] Tiki Wiki CMS Groupware 认证绕过漏洞CVE-2020-15906
    鹅长微服务发现与治理巨作PolarisMesh实践-上
    SOA和ESB介绍
  • 原文地址:https://blog.csdn.net/qq_44554428/article/details/126590990