zoukankan      html  css  js  c++  java
  • 秒表

    源码上传:https://github.com/data1213/-

    1、UI设计:

    2、代码:

    Qtime、Qtimer类

    需求:每隔1ms,更新显示,怎么通知计时周期到:

    QTimer类帮助文档:

    1       QTimer *timer = new QTimer(this);
    2       connect(timer, SIGNAL(timeout()), this, SLOT(update()));
    3       timer->start(1000);  //1s

    怎么获取时间数据:QTime帮助文档:

    1 QTime 定义一个对象,它可以记录时间,并且可以人为指定时间,还有addMSecs方法可以实现增加指定毫秒,从而达到计数。

     1 Example:
     2 
     3   QTime n(14, 0, 0);                // n == 14:00:00
     4   QTime t;
     5   t = n.addSecs(70);                // t == 14:01:10
     6   t = n.addSecs(-70);               // t == 13:58:50
     7   t = n.addSecs(10 * 60 * 60 + 5);  // t == 00:00:05
     8   t = n.addSecs(-15 * 60 * 60);     // t == 23:00:00
     9 
    10 See also addMSecs(), secsTo(), and QDateTime::addSecs().

    通过toString方法可以获取一个QString类型的时间字符串:

    1 QString QTime::toString(const QString &format) const
    2 
    3 
    4 Format ---> Result
    5 hh:mm:ss.zzz              14:13:09.042
    6 h:m:s ap                  2:13:9 pm
    7 H:m:s a                   14:13:9 pm

    怎么显示到QLCDNumber控件:QLCDNumber帮助文档:

    1 [slot] void QLCDNumber::display(const QString &s)
    2 Displays the number represented by the string s.

    这里的display方法是一个槽函数,这就是说明,槽函数可以像普通函数一样被调用,而不一定非要绑定信号才能调用。

     1 #ifndef MAINWINDOW_H
     2 #define MAINWINDOW_H
     3 
     4 #include <QMainWindow>
     5 #include <QTime>
     6 #include <QTimer>
     7 
     8 namespace Ui {
     9 class MainWindow;
    10 }
    11 
    12 class MainWindow : public QMainWindow
    13 {
    14     Q_OBJECT
    15 
    16 public:
    17     explicit MainWindow(QWidget *parent = nullptr);
    18     ~MainWindow();
    19 
    20 
    21 private slots:
    22     void update_my_timer();
    23 
    24     void on_btn_begin_clicked();
    25 
    26 private:
    27     QTime count_time;       //计数,用于更新定时器
    28     QTimer* p_timer;        //定时器
    29     Ui::MainWindow *ui;
    30 };
    31 
    32 #endif // MAINWINDOW_H
     1 #include "mainwindow.h"
     2 #include "ui_mainwindow.h"
     3 #include <QDebug>
     4 
     5 MainWindow::MainWindow(QWidget *parent) :
     6     QMainWindow(parent),
     7     ui(new Ui::MainWindow)
     8 {
     9     ui->setupUi(this);
    10     this->p_timer = new QTimer();
    11     connect(this->p_timer, SIGNAL(timeout()), this, SLOT(update_my_timer())); //绑定定时器和槽函数
    12 
    13 }
    14 
    15 MainWindow::~MainWindow()
    16 {
    17     delete ui;
    18 }
    19 
    20 
    21 //计时周期到响应的槽函数
    22 void MainWindow::update_my_timer(){
    23     //1、更新当前计数
    24     this->count_time = this->count_time.addMSecs(1); //增加1ms
    25     //2、控件显式更新
    26     QString timev = this->count_time.toString("hh:mm:ss.zzz");
    27     qDebug()<<timev;
    28     this->ui->lcdNumber->display(timev);
    29 
    30 }
    31 
    32 //点击开始按钮之后触发计时器开始计时
    33 void MainWindow::on_btn_begin_clicked()
    34 {
    35     this->p_timer->start(1);  //启动1ms周期的定时器开始计时
    36     //0、清空计数
    37     this->count_time.setHMS(0,0,0,0);
    38 }

    效果:

    改进:这里在设置计数时,认为设定从00:00:00:00开始,并且1ms计时周期,较短,需要处理的函数调用较多,这样容易出现问题,比如:当前进程较多,count_timer的计数有可能没有计到数,这样显式出来的就是错误的。

    改进的做法:利用系统时间之差,来作为计数,这样系统时间始终是正确的,显式的始终是正确的。

    1 int QTime::msecsTo(const QTime &t) const    //返回两个QTime之间的ms差
    2 [static] QTime QTime::currentTime()
     1 //计时周期到响应的槽函数
     2 void MainWindow::update_my_timer(){
     3     //记录当前时间
     4     QTime c_time = QTime::currentTime();
     5     int diff = this->count_time.msecsTo(c_time);
     6 
     7     QTime temp;
     8     temp.setHMS(0,0,0,0);
     9 
    10     temp = temp.addMSecs(diff);
    11     QString str = temp.toString("hh:mm:ss.zzz");
    12     this->ui->lcdNumber->display(str);
    13 
    14 }
    15 
    16 //点击开始按钮之后触发计时器开始计时
    17 void MainWindow::on_btn_begin_clicked()
    18 {
    19     this->p_timer->start(1);  //启动1ms周期的定时器开始计时
    20     //0、记录当前时间
    21     this->count_time = QTime::currentTime();
    22 }

    功能完善以及按钮逻辑设定:

     1 #ifndef MAINWINDOW_H
     2 #define MAINWINDOW_H
     3 
     4 #include <QMainWindow>
     5 #include <QTime>
     6 #include <QTimer>
     7 
     8 namespace Ui {
     9 class MainWindow;
    10 }
    11 
    12 class MainWindow : public QMainWindow
    13 {
    14     Q_OBJECT
    15 
    16 public:
    17     explicit MainWindow(QWidget *parent = nullptr);
    18     ~MainWindow();
    19 
    20 
    21 private slots:
    22     void update_my_timer();
    23 
    24     void on_btn_begin_clicked();
    25 
    26     void on_btn_end_clicked();
    27 
    28     void on_btn_hold_clicked();
    29 
    30     void on_btn_flag_clicked();
    31 
    32 private:
    33     QTime count_time;       //计数,用于更新定时器
    34     QTimer* p_timer;        //定时器
    35     QString show_time;        //用于打点记录
    36     Ui::MainWindow *ui;
    37 };
    38 
    39 #endif // MAINWINDOW_H
      1 #include "mainwindow.h"
      2 #include "ui_mainwindow.h"
      3 #include <QDebug>
      4 
      5 MainWindow::MainWindow(QWidget *parent) :
      6     QMainWindow(parent),
      7     ui(new Ui::MainWindow)
      8 {
      9     ui->setupUi(this);
     10     this->p_timer = new QTimer();
     11     connect(this->p_timer, SIGNAL(timeout()), this, SLOT(update_my_timer())); //绑定定时器和槽函数
     12 
     13     //一开始只设置开始按钮可用
     14     this->ui->btn_hold->setEnabled(false);
     15     this->ui->btn_flag->setEnabled(false);
     16     this->ui->btn_end->setEnabled(false);
     17 
     18 
     19 }
     20 
     21 MainWindow::~MainWindow()
     22 {
     23     delete ui;
     24 }
     25 
     26 
     27 //计时周期到响应的槽函数
     28 void MainWindow::update_my_timer(){
     29     //记录当前时间
     30     QTime c_time = QTime::currentTime();
     31     int diff = this->count_time.msecsTo(c_time);
     32 
     33     QTime temp;
     34     temp.setHMS(0,0,0,0);
     35 
     36     temp = temp.addMSecs(diff);
     37     QString str = temp.toString("hh:mm:ss.zzz");
     38     this->ui->lcdNumber->display(str);
     39 
     40     //为了实现打点记录,这里先获取下当前时间
     41     this->show_time = str;
     42 
     43 }
     44 
     45 //点击开始按钮之后触发计时器开始计时
     46 void MainWindow::on_btn_begin_clicked()
     47 {
     48     this->p_timer->start(1);  //启动1ms周期的定时器开始计时
     49     //0、记录当前时间
     50     this->count_time = QTime::currentTime();
     51 
     52     //避免再次点击,需要设置开始按钮不可用
     53     this->ui->btn_begin->setEnabled(false);
     54     //其他按钮可用
     55     this->ui->btn_hold->setEnabled(true);
     56     this->ui->btn_flag->setEnabled(true);
     57     this->ui->btn_end->setEnabled(true);
     58 }
     59 
     60 void MainWindow::on_btn_end_clicked()
     61 {
     62     if(this->ui->btn_end->text() == "停止"){
     63         this->p_timer->stop();
     64         this->ui->btn_end->setText("清零");
     65 
     66         this->ui->btn_hold->setEnabled(false);  //暂停不可用,开始也还是不能用
     67 
     68         //如果是点击暂停按钮之后(本身变成继续)点击停止,那么需要将暂停按钮重新设置为暂停
     69         this->ui->btn_hold->setText("暂停");
     70 
     71     }else {  //清零
     72         this->ui->lcdNumber->display("00:00:00:000");
     73         this->ui->textBrowser->clear();
     74         this->ui->btn_end->setText("停止");
     75 
     76         this->ui->btn_begin->setEnabled(true);  //开始按钮重新可用
     77         //this->ui->btn_hold->setEnabled(false);//暂停继续不可用
     78         this->ui->btn_flag->setEnabled(false);
     79         this->ui->btn_end->setEnabled(false);
     80     }
     81 }
     82 
     83 //暂停功能
     84 void MainWindow::on_btn_hold_clicked()
     85 {
     86     //old_time需要时静态的,记录点击暂停时的时间,保留到下次调用该函数——点击继续时调用
     87     static QTime old_time;
     88 
     89     if(this->ui->btn_hold->text() == "暂停"){
     90         old_time = QTime::currentTime();
     91         this->p_timer->stop();//暂停计数,当系统时间一直在走,而count_timer没有变化了
     92         this->ui->btn_hold->setText("继续");
     93     }else {
     94         QTime new_time = QTime::currentTime();
     95         int mdiff = old_time.msecsTo(new_time);
     96         //更新从上一次点击暂停到这次点击继续之间系统经过的时间,然后补偿给count_timer
     97         this->count_time = this->count_time.addMSecs(mdiff);
     98         //开启计时器
     99         this->p_timer->start(1);
    100         this->ui->btn_hold->setText("暂停");
    101     }
    102 }
    103 
    104 //打点功能:
    105 void MainWindow::on_btn_flag_clicked()
    106 {
    107     //获取当前计数,并显式在text brower控件中显式
    108     //this->ui->lcdNumber->value();是一个double值,不是时间值
    109     //this->ui->textBrowser->setText()方法会覆盖之前的文本内容
    110     this->ui->textBrowser->append(this->show_time);
    111 }

    效果演示:

    内在的趣味,表面的繁琐
  • 相关阅读:
    影响Scala语言设计的因素列表
    mysql查询不区分大小写问题分析和解决
    mysql基础之三:char与varchar区别,varchar(M)能存多少
    Springboot Actuator之三:spring boot健康检查对Redis的连接检查的调整
    nginx实现带参数目录域名重定向二级域名方法
    Nginx正则表达式之匹配操作符详解
    微服务API网关 vs. 传统企业级API网关
    无法打开SQL Server的连接
    URAL 1146 Maximum Sum(最大子矩阵的和 DP)
    leetCode 70.Climbing Stairs (爬楼梯) 解题思路和方法
  • 原文地址:https://www.cnblogs.com/data1213/p/10808230.html
Copyright © 2011-2022 走看看