嵌入式Qt-做一个秒表
之前的文章:嵌入式Qt-动手编写并运行自己的第1个ARM-Qt程序
介绍了如何编写第一个嵌入式Qt程序,实现了一个电子时钟的演示。
本篇,继续进行Qt实践,仿照手机中的秒表,实现一个相同功能的秒表:
回顾上一次的Qt开发流程,整个Qt的开发都是通过敲代码实现的,实际上,还可以利用Qt Creater的UI界面功能,通过图像化的配置来开发图形界面,本篇就使用这种方法来进行开发。
1 新建Qt工程
Qt工程创建的具体步骤可参照之前的文章:嵌入式Qt-动手编写并运行自己的第1个ARM-Qt程序,这里只说明不同之处。
上篇是通过代码实现页面设计的,本篇要借助Qt Creater的UI界面设计功能,因此要把下面的创建页面勾选上:
创建完成之后的Qt默认工程结构如下:
双击widget.ui,即可打开UI设置页面,如下图:
这里先简单熟悉下各个功能区:
2 代码编写
2.1 ui界面设计
修改界面的尺寸,我的Linux板子屏幕的分辨率是800x480,因此调整到对应的尺寸:
从左侧拖入一个Label,然后可以修改字体的大小:
再从左侧拖入其它需要用到的组件(PushButton、TextBrower)和位置调节组件(弹簧形状的HorizontalSpacer、VericalSpacer)
进行水平布局和竖直布局,选中对应的组件,例如3个按钮和中间的2个弹簧,点击上方工具栏中的水平布局按钮:
3个按键的水平布局效果如下:
然后再依次对其它组件进行布局:
字体可以调整到居中显示:
鼠标选中最大的组合组件,拖拽边缘调整到合适的外尺寸。然后选中不同级别的组合组件,调整layoutStretch的参数,实现按比例显示各个组件(相当于调节各个弹簧组件的弹力大小)
点击左下角上面那个三角图标,运行,查看效果:
注意左边留的空白是给秒表的表盘留的。
2.2 QTimer与QTime介绍
QTimer 类为定时器提供了一个高级编程接口,提供重复和单次计时。
QTime 类提供时钟时间功能,QTime 对象包含一个时钟时间,它可以表示为自午夜以来的小时数、分钟数、秒数和毫秒数。
Qt Creater提供了方便的帮助文档,可以在Qt Creater中直接查看对应功能函数的使用,比如搜索QTimer,就可以看到对应的介绍,以及可用的API函数:
本篇需要用到QTimer的功能有:
- start:启动定时器
- stop:停止定时器
再看看QTime的介绍:
本篇需要用到QTime的功能有:
- setHMS:设置初始时间
- addMSecs:增加一个时间(毫秒单位)
- toString:时间转为字符串格式
- minute:获取分钟
- second:获取秒
- msec:获取毫秒
2.3 对应按钮的函数
为了编写出更易看懂的代码,在编写代码之前,需要修改对应的组件的默认名称为便于理解的名称,比如我将3个按键的名称分别改为了:
- Btn_Start:开始按钮,并同时具有暂停/继续功能
- Btn_Reset:复位按钮
- Btn_Hit:打点按钮,用于记录不同名次的时间
然后还要手动添加QTimer和QTime对象,用于实现秒表的计时功能:
2.3.1 开始按钮的处理
Qt编程中重要处理就是信号和槽机制,它可用通过手动通过connet函数实现,而对于使用Qt Creater的图形界面设计方式,通常也是继续通过界面实现信号和和槽的连接:在开始按钮上右键,选则“转到槽…”:
然后有多种按钮信号可以选择,因为开始按钮同时具有暂停/继续的功能,这里使用toggled功能,利用按钮的按下和松开状态,来实现暂停/继续的功能:
点击OK之后,会自动跳到到代码页面,并自动生成对应的槽函数框架,然后就可以在里面编译对应的业务逻辑代码了:
开始按钮的具体业务逻辑代码如下,当首次按下时,checked为true,此时启动timer,记录此时的时间戳,然后将按钮的文字显示为“暂停”,同时将复位和打点按钮置灰,使这两个按钮不能再按下,因为暂停的时候执行复位和打点无意义。
timer每隔一段时间会触发超时,这里ADD_TIME_MSEC设置的是30ms,超时时间到后,编写对应的超时处理函数timeout_slot以及声明对应的信号和槽的处理。
void Widget::on_Btn_Start_toggled(bool checked)
{if (checked){timer.start(ADD_TIME_MSEC);lastTime = QTime::currentTime();//记录时间戳ui->Btn_Start->setText("暂停");ui->Btn_Reset->setEnabled(false);ui->Btn_Hit->setEnabled(true);}else{timer.stop();ui->Btn_Start->setText("继续");ui->Btn_Reset->setEnabled(true);ui->Btn_Hit->setEnabled(false);}
}connect(&timer, SIGNAL(timeout()), this, SLOT(timeout_slot()));
void Widget::timeout_slot()
{//qDebug("hello");QTime nowTime = QTime::currentTime();time = time.addMSecs(lastTime.msecsTo(nowTime));lastTime = nowTime;ui->Txt_ShowTime->setText(time.toString("mm:ss.zzz"));
}
超时时间到了之后,计算一些两次的时间差值,然后通过addMSecs函数来累加时间。
2.3.2 复位按钮的处理
复位按钮也是通过右键来调整到槽,注意这里使用clicked函数即可,因为复位按钮只需要使用它的点击按下功能:
对应的槽函数的具体实现如下:
void Widget::on_Btn_Reset_clicked()
{m_iHitCnt = 0;timer.stop();time.setHMS(0,0,0,0);ui->Txt_ShowTime->setText("00:00:00");ui->Txt_ShowItem->clear();ui->Btn_Start->setText("开始");ui->Btn_Start->setChecked(false);ui->Btn_Reset->setEnabled(false);ui->Btn_Hit->setEnabled(false);
}
主要是将时间归零,将显示情况,并将各个按钮的显示状态复位为默认显示状态。
2.3.3 打点按钮的处理
打点按钮与复位按钮一样,也是只使用clicked函数即可,对应的槽函数的具体实现如下:
void Widget::on_Btn_Hit_clicked()
{QString temp;m_iHitCnt++;temp.sprintf("--计次 %d--", m_iHitCnt);ui->Txt_ShowItem->setFontPointSize(9);ui->Txt_ShowItem->append(temp);ui->Txt_ShowItem->setFontPointSize(12);ui->Txt_ShowItem->append(time.toString("[mm:ss.zzz]"));
}
打点功能用于在秒表的运行过程中,记录不同名次的时间,并显示在右侧的文本显示框中。
这里通过setFontPointSize函数来设置不同大小的字体显示。
2.4 秒表表盘的实现
之前这篇文章:嵌入式Qt-动手编写并运行自己的第1个ARM-Qt程序,通过代码的方式,实现了一个时钟表盘的显示,本篇在这个的基础上,修改代码,实现一个显示秒和分的秒表表盘,具体修改后的代码如下:
connect(&timer, SIGNAL(timeout()), this, SLOT(update()));
connect(ui->Btn_Reset, SIGNAL(clicked()), this, SLOT(update()));void Widget::paintEvent(QPaintEvent *event)
{int side = qMin(width(), height());//QTime time = QTime::currentTime();QPainter painter(this);painter.setRenderHint(QPainter::Antialiasing);painter.translate(width()/3, height()*2/5); //画图的基准位置painter.scale(side/300.0, side/300.0); //随窗口尺寸自动缩放//表盘(3个同心圆)for (int i=0; i<PANEL_RADIUS_NUM; i++){QBrush brush(stPanelParaArr[i].color);QPen pen(stPanelParaArr[i].color);painter.setBrush(brush);painter.setPen(pen);painter.drawEllipse(-stPanelParaArr[i].radius, -stPanelParaArr[i].radius, 2*stPanelParaArr[i].radius, 2*stPanelParaArr[i].radius);}//秒的刻度painter.setPen(secondColor);for (int i = 0; i < 60; i++){if ((i % 5) == 0){painter.drawLine(PANEL_RADIUS3-8, 0, PANEL_RADIUS3, 0);QFont font("TimesNewRoman", SEC_NUM_SIZE);painter.setFont(font);painter.drawText(-SEC_NUM_SIZE, -(CLOCK_RADIUS-15), 2*SEC_NUM_SIZE, 2*SEC_NUM_SIZE, Qt::AlignHCenter, QString::number(i==0? 60 : i));}else{painter.drawLine(PANEL_RADIUS3-5, 0, PANEL_RADIUS3, 0);}//秒再细分5个格for (int j = 0; j < 5; j++){painter.rotate(6.0/5);if (j != 4){painter.drawLine(PANEL_RADIUS3-2, 0, PANEL_RADIUS3, 0);}}}//分钟的刻度painter.setPen(minuteColor);for (int k = 0; k < 30; k++){if ((k % 5) == 0){painter.rotate(-90.0);painter.drawLine(PANEL_RADIUS4-8, 0, PANEL_RADIUS4, 0);painter.rotate(90.0);QFont font("TimesNewRoman", MIN_NUM_SIZE);painter.setFont(font);painter.drawText(-MIN_NUM_SIZE, -(PANEL_RADIUS4-10), 2*MIN_NUM_SIZE, 2*MIN_NUM_SIZE, Qt::AlignHCenter, QString::number(k==0? 30 : k));}else{painter.rotate(-90.0);painter.drawLine(PANEL_RADIUS4-4, 0, PANEL_RADIUS4, 0);painter.rotate(90.0);}painter.rotate(12.0);}//分钟的表针painter.setPen(Qt::NoPen);painter.setBrush(minuteColor);painter.save();painter.rotate(12.0 * (time.minute() + time.second() / 60.0));painter.drawConvexPolygon(minuteHand, 3);painter.restore();//秒钟的表针painter.setPen(Qt::NoPen);painter.setBrush(secondColor);painter.save();//painter.rotate(6.0 * time.second());painter.rotate(6.0 * (time.second()+time.msec()/1000.0));painter.drawConvexPolygon(secondHand, 3);painter.restore();painter.end();
}
主要修改是将之前的小时显示去掉,并改为两个时间环:外圈秒环和内圈分环,秒环的范围是060秒,分环的范围是030分。
秒表表盘的显示效果如下:
3 编译运行
代码是在Window环境中的Qt Creater中编写的,首先是Windows中编译查看效果。
3.1 Windows中编译
在Windows中的运行效果如下图的右图,可以实现手机中秒表类似的计时效果:
3.2 Ubuntu中编译
将Windows中的QT工程源码:
- .cpp文件
- .h文件
- .pro文件
- .ui文件
复制到Ubuntu中,注意.user文件是不需要的(它是Windows平台的编译配置)。
然后使用ARM平台的编译工具链,我的是在”/home/xxpcb/myTest/imx6ull/otherlib/qt/qt-everywhere-src-5.12.9/arm-qt/“,这里需要先用到它的qmake工具先自动生成Makefile文件,再通过make指令进行编译。
使用qmake生成Makefile,进入程序源码目录,执行qmake指令:
/home/xxpcb/myTest/imx6ull/otherlib/qt/qt-everywhere-src-5.12.9/arm-qt/bin/qmake
成功执行之后,就可以看到自动生成的Makefile文件,然后执行make指令进行编译得到可执行文件。
3.3 Linux板子中运行
将可执行文件放到已配置了qt运行环境的Linux板子中,运行并查看效果:
https://www.bilibili.com/video/BV1XW4y1y7pK
注:
Ubuntu中的具体编译过程,可参考之前这篇文章:嵌入式Qt-动手编写并运行自己的第1个ARM-Qt程序
Ubuntu中Qt的交叉编译环境的配置,可参考之前这篇文章:嵌入式Linux-Qt环境搭建
4 总结
本篇通过一个秒表的实例,介绍了如何使用Qt Creator的UI界面设计功能,进行Qt的开发,并将代码进行交叉编译,放入i.MX6ULL的Linux环境中测试运行情况。
嵌入式Qt-做一个秒表相关推荐
- 使用Qt做一个简单计算器
title: Calculator date: 2022-09-04 11:10:12 tags: [Qt, 应用, C++] typora-root-url: Calculator 使用Qt做一个简 ...
- 嵌入式Qt 开发一个视频播放器
上篇文章:嵌入式 Qt开发一个音乐播放器,使用Qt制作了一个音乐播放器,并在OK3568开发板上进行了运行测试,实际测试效果还不错. 本篇继续来实现一个Qt视频播放器软件,可以实现视频列表的显示与选择 ...
- 用 定时计数器中断 和 动态八段数码管 做一个秒表
用 定时/计数器中断 和 动态八段数码管做一个秒表 目录 用 定时/计数器中断 和 动态八段数码管做一个秒表 1.思路 定时器 数码管 2.主要代码讲解 3.全部代码参考(代码写的很烂,欢迎提出建议) ...
- 新手如何用QT做一个“动漫宠物“?进来学!!!!
好久不见,又是这样的深夜,也算是忙里偷闲,分享下我前一段时间写的QT小玩具吧 交流群 1.效果展示 2.灵感 3.思路 4.代码部分 源码 交流群 698742127 想学习的小伙伴可以加一下,可以一 ...
- 用QT做一个rtsp / rtmp实时流的播放器 ffmpeg
老早之前用qt集成ffmpeg 做过一个播放器 那个是基于sdl的命令行窗口 这次做成GUI的方式 直接做成一个播放器 可以输入rtsp或者rtmp流地址 效果图如下 那个长的输入框输入rtsp地址 ...
- python秒表模块_利用python的kivy模块做一个秒表
Kiy是一个开源的Python模块库,用于开发界面应用程序和其它采用自然用户界面的多点触控应用软件.它可以在Android,iOS,Linux,OS X和Windows执行,是一款有趣跨平台的模块库. ...
- python+Qt做一个身高识别辅助器,告别动脑思考的烦恼
直接上才艺 # -*- coding: utf-8 -*-# Form implementation generated from reading ui file '身高.ui' # # Create ...
- QT实现一个图片透视变换的小玩意
近来有点烦,不想看论文,不想做项目,无聊之余把好久之前想到的用qt做一个图片透视变换的小工具的想法实现了一下...详细如下: 说明:对于有些平时拍的图片可能产生了透视效果,而你想得到正向拍摄的效果,你 ...
- 用js做一个简单的秒表计时器
用js做一个简单的秒表计时器 具体代码如下 <!DOCTYPE html> <html lang="en"><head><meta cha ...
- 一、Qt初尝试,做一个QT计算器《QT 入门到实战》
学习目标 了解 qt 的基本信息 了解 qt 的下载及安装 了解创建一个基本 qt 项目的流程 了解信号与槽 通过示例了解信号与槽的设置与编写 了解控件添加的方式 了解控件如何使用代码获取其文本 了解 ...
最新文章
- 面试:什么是序列化,怎么序列化,为什么序列化,反序列化会遇到什么问题,如何解决?...
- 转:并口编程参考资料
- Comware、VRP、IOS这些操作系统平台你分清了吗?
- 【小米校招笔试】给定一些线段,线段有起点和终点,求这些线段的覆盖长度,重复的部分只计算一次
- object-c编程tips-timer
- python——学习笔记1
- 工业控制中无线局域网应用前景分析
- ijkPlayer 集成
- Alpha冲刺(2/10)——2019.4.24
- AsciidocFX相关
- solr学习笔记-linux下配置solr
- 大话数据结构学习笔记
- android 连接魅族手机,android studio连接魅族真机
- 小摩尔来了!3分钟带你做个魔性小摩尔!
- 面试常见逻辑题小整理
- aka鉴权 ims_宋月:IMS鉴权过程中各参数的用途
- 定时任务每隔10分钟
- [Unity3D] MoveTowards、Lerp、Slerp
- 数据结构与算法之一(书籍篇)
- 广数GSK(980, 988, 980tdi网口,980tdc串口)数据采集实战
热门文章
- cuba_CUBA 7的新功能
- 为什么我不给孩子看国产动漫?看看这5部法国动漫,你就知道了!【转】
- DiMP:Learning Discriminative Model Prediction for Tracking
- ffmpeg 自定义IO与Seek
- 读一封汶川地震的信:亲爱的,我要和别人结婚了
- 写出linux命令的功能,练习一LINUX命令测试题1
- 北京仁源欣生获200万美元天使轮融资,和玉资本领投...
- Java在线预览(word转html)--强势推荐
- 如何计算DDR存储容量
- 飞秋2013正式版有偿修改在线等