做"计时器"需要用到两个类:
- QTime:时间数据类型,仅表示时间,如15:23:13;相当于手表。
- QTimer:qt的定时类,相当于秒表。
设计思路跟之前的设计一样,都是先设计ui界面,然后再实现逻辑功能。
第一部分:设计ui界面
(1)选择好需要的控件
计时器显示时间的窗口用Label来实现,还需要有几个按钮(开始、关闭、重置、打点),还要将时间保存在一个窗口里面(Text Browser)
(2)界面布局并编译运行
(3)给控件修改名字
第二部分:编写逻辑代码
(1)包含所用类的头文件
(2)创建类对象(在public下定义所用类的"对象")
(3)信号和槽
<1>.“开始”功能设置-----在ui界面点击“开始”按钮的时候,就会开始计时。对“开始”按钮使用自动关联。在“索引”里面查找QTimer的相关信息,可以看到有start信号。
void start(int msec);
函数功能:开启定时器,时间到后发出 timeout 信号,并重新计时。
参数 msec 含义:定时时间,单位毫秒。
开启计时器对象,设置定时时间,时间到后会发出 timeout() 信号,绑定此信号和自定义的槽函数 timeOut_Slot()。
Widget::Widget(QWidget *parent) :
QWidget(parent),
ui(new Ui::Widget)
{
ui->setupUi(this);
//手动关联信号和槽timeout_slot()
connect(&timer,SIGNAL(timeout()),this,SLOT(timeout_slot()));
}
绑定好信号和槽之后,可以在槽函数的实现里面先测试一下,将start信号的参数写为1000毫秒(1秒),令其输出“time out时间到了”。编译运行,看看是否为每隔一秒就打印信息。测试结果如下:
定时器第一步要进行初始化,设置一下时间,为了更精确,将单位精准到毫秒,将初始时间设置为00:00:00:000。
在“索引”里面查找QTime类的相关信息,可以看到它的公共成员函数大部分都是跟时间相关的,后面的代码设计会用到一些。
第二步是要进行计时。如何计时呢?上面提到了每隔一秒钟就打印“time out时间到了”的方法,现在是要每隔一秒钟让程序进入一次timeout槽函数来刷新时间,由于初始化时设置的时间单位精确到了毫秒,故将"开始"按钮里面的时间暂且改为30,意为30毫秒。
void Widget::timeout_slot()
{
time =time.addMSecs(40);//每隔40毫秒就进一次,每进一次就加40毫秒
//然后令这个功能在ui界面显示出来
ui->showTime->setText(time.toString("hh:mm:ss.zzz"));//设置tostring的格式之后编译看一下
}
void Widget::on_startBt_clicked()
{
timer.start(30);//每隔30毫秒就进入一次timeout_slot()槽函数
}
tostring的格式:
<2>“关闭”按钮
仍然采用的是信号和槽的自动关联
void Widget::on_closeBt_clicked()
{
timer.stop();//stop
}
根据功能,感觉这个按钮叫做“停止”会更合适,修改一下名字(关闭—>停止)。
<3>"重置"按钮
“自动关联”—》“重置”(重置其实就相当于是初始化)
void Widget::on_resetBt_clicked()
{
//重置功能包括停止并清空
timer.stop();
time.setHMS(0,0,0,0);
ui->showTime->setText("00:00:00:000");
}
<4>“打点”按钮(选择“自动关联”)
打点功能就是开始之后,每按一次就记录下当时打点时的时间并显示在Text Browser里面。
void Widget::on_bitBt_clicked()
{
//只需要将当前时间显示在框里
ui->bitTime->append(time.toString("hh:mm:ss.zzz"));
}
第三部分:功能验证
在上述设计的基础上,如果在打点的后面再添加一个排名,这个设计的功能就更完善且人性化了。在“打点”功能的槽函数处添加几句代码:
void Widget::on_bitBt_clicked()
{
QString temp;
i=i+1;
temp.sprintf("%d:",i);
ui->bitTime->append(temp);
ui->bitTime->append(time.toString("hh:mm:ss.zzz"));
}
验证功能:
还有一点需要完善,点击“重置”之后,显示框里面并不会清空,这是前面设计的缺陷,来调整一下,给“重置”按钮的槽函数实现加上一条代码:
//清空显示框
ui->bitTime->clear();
i=0;
这样一来,重置的时候时间回到了起点00:00:00:000,显示框也清空啦。