@

1.前言

之前我使用在桌面版本Qt实现了肺炎疫情监控平台:基于Qt的新冠肺炎疫情数据实时监控平台(开源小项目)。既然Qt是跨平台的,正好手里有一块iMX287A的开发套件,含一块4.3寸的显示屏,那么能不能在嵌入式平台实现一下呢?

最后实现的效果:

2.数据接口的获取

疫情监控平台的实现,简单的说,就是数据的展示,而数据从哪里来呢?现在很多互联网公司都做了自己的疫情监控平台,我这里采用的是腾讯新闻的数据源,数据内容比较丰富,也比较稳定。

数据来源:实时更新:新冠肺炎疫情最新动态

接口地址的获取方法可以参考:基于Qt的新冠肺炎疫情数据实时监控平台(开源小项目)

如果把所有的数据放在一个接口里,数据量会很大,腾讯把数据分成了几个接口

  1. #包含最新疫情数据、各省市最新数据、其他国家最新数据
  2. https://view.inews.qq.com/g2/getOnsInfo?name=disease_h5
  3. #包含历史数据d
  4. https://view.inews.qq.com/g2/getOnsInfo?name=disease_other
  5. #最新的辟谣信息
  6. https://vp.fact.qq.com/loadmore?page=0
  7. #辟谣信息详情
  8. https://vp.fact.qq.com/miniArtData?id=a2141851348ee5f3772c761e25bb57d7

由于液晶屏幕太小,只有4.3寸,分辨率也比较低480 × 272,显示不了太多的内容,所以我们只使用到了https://view.inews.qq.com/g2/getOnsInfo?name=disease_h5这个接口中的chinaTotalchinaAdd这两组数据。

这个接口包括很多数据,全国累计和新增的最新数据,各省市其他国家的最新数据等等。文件大小大概在160KB。

数据格式:

  1. {
  2. "ret": 0,
  3. "data": {
  4. "lastUpdateTime": "2020-03-04 11:12:04",
  5. "chinaTotal": {
  6. "confirm": 80422,
  7. "heal": 49914,
  8. "dead": 2984,
  9. "nowConfirm": 27524,
  10. "suspect": 520,
  11. "nowSevere": 6416
  12. },
  13. "chinaAdd": {
  14. "confirm": 120,
  15. "heal": 2654,
  16. "dead": 38,
  17. "nowConfirm": -2572,
  18. "suspect": -67,
  19. "nowSevere": -390
  20. },
  21. ...........其他数据.............
  22. "isShowAdd": true
  23. }
  24. }

3.Qt界面的实现

之前的应用程序中,是使用的Qt5版本开发的,Qt5自带QJson解析类,而Qt 4没有带QJson,所以只能使用第三方JSON解析库,我这里选择的小巧的cJSON解析库:cJSON download | SourceForge.net

只包含两个文件:cJSON.c和cJSON.h,把这两个文件添加到工程里就行了。

代码也很简单:GET接口地址,把接收到的数据保存到本地,调用cJSON解析数据文件,把解析出的数据显示,数据文件删除。代码可以到文章末尾开源地址获取。下面介绍一个几个关键部分代码的实现:

3.1 JSON数据的解析

  1. //打开保存的JSON数据文件,并调用解析函数
  2. void Dialog::parseData(QString filename)
  3. {
  4. QFile file(filename);
  5. if(!file.open(QIODevice::ReadOnly))
  6. {
  7. qDebug() << "file open failed";
  8. return;
  9. }
  10. QByteArray allData = file.readAll();
  11. file.close();
  12. // qDebug() << allData;
  13. getData(allData);
  14. file.remove(); //删除文件
  15. return;
  16. }
  17. //把数据解析出来并显示在标签上
  18. void Dialog::getData(QByteArray str)
  19. {
  20. cJSON *ret_obj;
  21. cJSON *root_obj;
  22. root_obj = cJSON_Parse(str); //创建JSON解析对象,返回JSON格式是否正确
  23. if (!root_obj)
  24. {
  25. disInfo("JSON format error");
  26. qDebug() << "json format error";
  27. }
  28. else
  29. {
  30. disInfo("json format ok");
  31. qDebug() << "json format ok";
  32. ret_obj = cJSON_GetObjectItem(root_obj, "ret");
  33. if(cJSON_IsNumber(ret_obj))
  34. {
  35. int ret = 1;
  36. ret = ret_obj->valueint;
  37. // qDebug() << ret_obj->valueint;
  38. }
  39. char *data_str = cJSON_GetObjectItem(root_obj, "data")->valuestring;
  40. cJSON *data_obj = cJSON_Parse(data_str);
  41. if(!data_obj)
  42. {
  43. qDebug() << "data json err";
  44. cnt_error++;
  45. QString error = "err:" + QString::number(cnt_error);
  46. ui->lbe_error->setText(error);
  47. }
  48. else
  49. {
  50. qDebug() << "data json ok";
  51. char *lastUpdateTime = cJSON_GetObjectItem(data_obj, "lastUpdateTime")->valuestring;
  52. qDebug() << lastUpdateTime;
  53. ui->lbe_update_time->setText(lastUpdateTime);
  54. cJSON *chinaTotal_obj = cJSON_GetObjectItem(data_obj, "chinaTotal");
  55. int chinaTotal_confirm = cJSON_GetObjectItem(chinaTotal_obj, "confirm")->valueint;
  56. int chinaTotal_heal = cJSON_GetObjectItem(chinaTotal_obj, "heal")->valueint;
  57. int chinaTotal_dead = cJSON_GetObjectItem(chinaTotal_obj, "dead")->valueint;
  58. int chinaTotal_nowConfirm = cJSON_GetObjectItem(chinaTotal_obj, "nowConfirm")->valueint;
  59. int chinaTotal_suspect = cJSON_GetObjectItem(chinaTotal_obj, "suspect")->valueint;
  60. int chinaTotal_nowSevere = cJSON_GetObjectItem(chinaTotal_obj, "nowSevere")->valueint;
  61. ui->lbe_total_confirm->setNum(chinaTotal_confirm);
  62. ui->lbe_total_heal->setNum(chinaTotal_heal);
  63. ui->lbe_total_dead->setNum(chinaTotal_dead);
  64. ui->lbe_total_nowConfirm->setNum(chinaTotal_nowConfirm);
  65. ui->lbe_total_suspect->setNum(chinaTotal_suspect);
  66. ui->lbe_total_nowSevere->setNum(chinaTotal_nowSevere);
  67. cJSON *chinaAdd_obj = cJSON_GetObjectItem(data_obj, "chinaAdd");
  68. int chinaAdd_confirm = cJSON_GetObjectItem(chinaAdd_obj, "confirm")->valueint;
  69. int chinaAdd_heal = cJSON_GetObjectItem(chinaAdd_obj, "heal")->valueint;
  70. int chinaAdd_dead = cJSON_GetObjectItem(chinaAdd_obj, "dead")->valueint;
  71. int chinaAdd_nowConfirm = cJSON_GetObjectItem(chinaAdd_obj, "nowConfirm")->valueint;
  72. int chinaAdd_suspect = cJSON_GetObjectItem(chinaAdd_obj, "suspect")->valueint;
  73. int chinaAdd_nowSevere = cJSON_GetObjectItem(chinaAdd_obj, "nowSevere")->valueint;
  74. lbeDisplay(ui->lbe_add_confirm, chinaAdd_confirm);
  75. lbeDisplay(ui->lbe_add_heal, chinaAdd_heal);
  76. lbeDisplay(ui->lbe_add_dead, chinaAdd_dead);
  77. lbeDisplay(ui->lbe_add_nowConfirm, chinaAdd_nowConfirm);
  78. lbeDisplay(ui->lbe_add_suspect, chinaAdd_suspect);
  79. lbeDisplay(ui->lbe_add_nowSevere, chinaAdd_nowSevere);
  80. }
  81. // cJSON_Delete(ret_obj);
  82. // cJSON_Delete(data_obj);
  83. cJSON_Delete(root_obj);//释放内存
  84. disInfo("更新完成");
  85. cnt_success++;
  86. QString success = "ok:" + QString::number(cnt_success);
  87. ui->lbe_success->setText(success);
  88. }
  89. }
  90. //数据的显示
  91. void Dialog::lbeDisplay(QLabel *lbe, int num)
  92. {
  93. if(num > 0)
  94. lbe->setText("+" + QString::number(num));
  95. else
  96. lbe->setText(QString::number(num));
  97. }

3.2 根据编译器的版本自动调整窗口大小

  1. void Dialog::setLocation()
  2. {
  3. const QRect availableSize = QApplication::desktop()->availableGeometry(this);
  4. qint32 DESKTOP_QT4 = 264199;
  5. qint32 DESKTOP_QT5 = 329728;
  6. qint32 ARM_IMX287 = 263939;
  7. qint32 ARM_YA157C = 264199;
  8. //output current qt version id
  9. qDebug() << QT_VERSION;
  10. //output curretn screen resolution ratio
  11. qint16 width = availableSize.width();
  12. qint16 height = availableSize.height();
  13. qDebug() << "width: " << width << "height:" << height;
  14. if(QT_VERSION == ARM_IMX287)
  15. this->resize(width-5, height-15);
  16. else
  17. this->resize(width/3, height/3);
  18. qint16 loc_width = this->width();
  19. qint16 loc_height = this->height();
  20. qint16 loc_x = (width - loc_width) / 2;
  21. qint16 loc_y = (height - loc_height) / 2;
  22. qDebug() << "locx:" << loc_x << "locy" << loc_y;
  23. if(QT_VERSION == ARM_IMX287)
  24. this->move(0, 0);
  25. else
  26. this->move(loc_x, loc_y);
  27. }

3.3 获取本地IP地址

  1. //forexamle:192.168.1.111
  2. QString Dialog::GetLocalmachineIP()
  3. {
  4. QString ipAddress;
  5. QList<QHostAddress> ipAddressesList = QNetworkInterface::allAddresses();
  6. for(QHostAddress &addr : ipAddressesList)
  7. {
  8. // 找到不是本地ip,并且是ipv4协议,并且不是169开头的第一个地址
  9. if(addr != QHostAddress::LocalHost && addr.protocol() == QAbstractSocket::IPv4Protocol && !addr.toString().startsWith("169"))
  10. {
  11. ipAddress = addr.toString();
  12. break;
  13. }
  14. }
  15. // if we did not find one, use IPv4 localhost
  16. if (ipAddress.isEmpty())
  17. ipAddress = QHostAddress(QHostAddress::LocalHost).toString();
  18. return ipAddress;
  19. }

桌面Linux版本的运行效果:

4.在开发板上运行Qt程序

如果在桌面运行正常,就可以使用iMX287A开发套件来构建工程,生成可以在iMX287A运行的程序,使用scp命令传输到开发板上还需要使用udhcpc命令来自动获取路由器获取的IP地址,并连接上互联网。

  1. #使用网线把开发板连接上路由器
  2. #使用udhcpc自动获取IP地址
  3. udhcpc
  4. #确认连接到互联网
  5. ping www.baidu.com
  6. #如果有回复数据,说明已经成功连接上互联网
  7. #查看获取到的ip地址
  8. ifconfig
  9. #使用scp命令或共享目录的方式把可执行文件传输到开发板上
  10. scp imx287a_qt_ncov root@192.168.1.109:/root
  11. #执行程序
  12. ./imx287a_qt_ncov

5.最终效果

开发板运行效果



这个版本是上一个版本的,右上角没有显示开发板的IP地址,和成功失败次数统计,最新版本的程序中已经添加了这个功能。

桌面Linux版效果:

6.代码下载

代码已经开源在Github,如果下载速度很慢,可以选择国内的Gitee速度会快很多。

  1. #Github
  2. https://github.com/whik/qte_2019_ncov
  3. #Gitee
  4. https://gitee.com/whik/qte_2019_ncov

我的公众号:mcu149

iMX287A基于嵌入式Qt的新冠肺炎疫情监控平台的更多相关文章

  1. python画新冠肺炎国内和世界各国累计确诊数量热图

    新冠肺炎国内疫情基本控制住,很多地方都开始摘下口罩了.但是国外的疫情依然处于爆发期,特别是美国,截止目前其累计确诊数量已突破110w.五一节北京柳絮杨絮满天飞,不适合外出.在家心血来潮,献丑画一下各地 ...

  2. 参加Folding@Home(FAH)项目,为战胜新冠肺炎贡献出自己的一份力量

    鉴于新冠病毒(COVID-19)在全球范围内的大规模传播,PCMR和NVIDIA呼吁全球PC用户加入Folding@home项目贡献自己闲置的GPU计算力,协助抗击新冠状病毒疫情. 目前全球有超过40 ...

  3. 矩池云 | 新冠肺炎防控:肺炎CT检测

    连日来,新型冠状病毒感染的肺炎疫情,牵动的不仅仅是全武汉.全湖北,更是全国人民的心,大家纷纷以自己独特的方式为武汉加油!我们相信坚持下去,终会春暖花开. 今天让我们以简单实用的神经网络模型,来检测肺炎 ...

  4. LabVIEW+OpenVINO在CPU上部署新冠肺炎检测模型实战

    前言 之前博客:[YOLOv5]LabVIEW+OpenVINO让你的YOLOv5在CPU上飞起来给大家介绍了在LabVIEW上使用openvino加速推理,在CPU上也能感受丝滑的实时物体识别.那我 ...

  5. 我用STM32MP1做了个疫情监控平台2—Qt环境搭建

    目录 1.嵌入式Qt简介 2.查看开发板Qt库的版本 3.主机搭建Qt环境 4.第一个Qt程序--Hello World 5.一些问题 @ 1.嵌入式Qt简介 Qt 是一个跨平台的应用程序开发框架.使 ...

  6. 基于BootStrap框架构建快速响应的GPS部标监控平台

    最近一个客户要求将gps部标平台移植到bootStrap框架作为前端框架,符合交通部796部标只是他们的一个基本要求,重点是要和他们的冷链云物流平台进行适配.我自己先浏览了客户的云物流平台的界面,采用 ...

  7. 基于java spring框架开发部标1078视频监控平台精华文章索引

    部标1078视频监控平台,是一个庞杂的工程,涵盖了多层协议,部标jt808,jt809,jt1078,苏标Adas协议等,多个平台功能标准,部标796标准,部标1077标准和苏标主动安全标准,视频方面 ...

  8. 探索新冠肺炎(COVID-19)对全球航班的影响

    Cesium中文网:http://cesiumcn.org/ | 国内快速访问:http://cesium.coinidea.com/ 随着今天从欧洲到美国的旅行限制生效,以及为了减缓新冠病毒的传播更 ...

  9. 面试刷题27:程序员如何防护java界的新冠肺炎?

    背景 安全是软件设计的第二个非功能性需求,一般是当软件出现安全问题的时候才会得到重视. 最明显的比如 数据库用户信息和密码泄漏等: 数据加解密技术 单向加密 md5+salt值, 这个是软件设计中使用 ...

随机推荐

  1. 字符串常用方法总结与StringBuffer基础

    字符串 基本特性 final:字符串被修饰为final,是不能被继承的. immutable:字符串是不可改变的,例如创建了一个字符串对象,就不可改变它,即不能进行增删查改其中的字符.一旦创建好这个字 ...

  2. 十九、linux--RAID详解

    一.什么是RADI Raid是廉价冗余磁盘阵列,简称磁盘阵列. 运维人员就叫RAID.Raid是一种把多块独立的磁盘(物理磁盘)按不同方式组合起来形成一个磁盘组,在逻辑上看起来就是一个大的磁盘,从而提 ...

  3. 替换String中的\r\n\t

    String json = "<?xml version=\"1.0\" encoding=\"UTF-8\" ?>\r\n " ...

  4. conditon 实现等待/通知

    synchronized 与wait() 和notify() notifyAll() 方法相结合可以实现等待 通知 ReetrantLock也可以实现同样的功能 需要借助condition对象,一个l ...

  5. php测试使用小的mysql存储过程

    <?php //前提是php.ini里面要开通mysqli的扩展./*$link = mysqli_connect('localhost','root','','chinatupai');  $ ...

  6. SpringBoot开发二十-Redis入门以及Spring整合Redis

    安装 Redis,熟悉 Redis 的命令以及整合Redis,在Spring 中使用Redis. 代码实现 Redis 内置了 16 个库,索引是 0-15 ,默认选择第 0 个 Redis 的常用命 ...

  7. django操作非ORM创建的表

    问题:django的ORM怎么连接已存在的表,然后进行增删查改操作?     工作中会遇见很多二次开发的时候,表都是已经创建好的,用django的ORM进行二次开发,怎么操作数据库中的表呢? 下面介绍 ...

  8. “大屏,您好!” SONIQ声光揭新品“U•F•O”神秘面纱

    作为全球第一批做互联网智能电视的传媒企业,SONIQ声光于4月22日在中国大饭店举行了盛大的新品发布会.其中的重头戏就是当天发布会上作为先锋部队入驻中国电视市场的"UFO".笔者作 ...

  9. URI和URL对比

    URL是Uniform Resoure Locator(统一资源定位器)的缩写.就是WWW页的地址. 其URL地址格式排列为:scheme://host:Port/path --Internet资源类 ...

  10. linux下的时区修改

    Centos 7时区问题: 通常使用tzselect命令选择时区,今天在修改centos7的时区的时候,修改完以后时区还是没有发生变化,重启也是没有用的:通过网络的帮助了解到,在Centos和ubun ...