1.前言
之前我使用桌面版本qt实现了肺炎疫情监控平台:。
既然qt是跨平台的,正好手里有一块米尔科技的ya157c开发板,那么能不能在嵌入式平台实现一下呢?
桌面linux版本的运行效果:
ya157c开发板实现效果:
2.数据接口的获取
疫情监控平台的实现,简单的说,就是数据的展示,而数据从哪里来呢?
现在很多互联网公司都做了自己的疫情监控平台,我这里采用的是腾讯新闻的数据源,数据内容很丰富,也比较稳定。
数据来源:
接口地址的获取方法可以参考:
如果把所有的数据放在一个接口里,数据量会很大,所以腾讯把数据分成了几个接口
#包含最新疫情数据、各省市最新数据、其他国家最新数据
https://view.inews.qq.com/g2/getonsinfo?name=disease_h5
#包含历史数据
https://view.inews.qq.com/g2/getonsinfo?name=disease_other
#最新的辟谣信息
https://vp.fact.qq.com/loadmore?page=0
#辟谣信息详情
https://vp.fact.qq.com/miniartdata?id=a2141851348ee5f3772c761e25bb57d7
目前只显示了一些基本的数据,所以我们只使用到了https://view.inews.qq.com/g2/getonsinfo?name=disease_h5
这个接口中的chinatotal
和chinaadd
这两组数据。
这个接口包括很多数据,全国累计和新增的最新数据,各省市其他国家的最新数据等等。文件大小大概在160kb,液晶屏是7寸ips屏,1024x600分辨率的,还是比较大的,可以显示很多信息,后续版本会添加更多数据显示的。
数据格式:
{ "ret": 0, "data": { "lastupdatetime": "2020-03-04 11:12:04", "chinatotal": { "confirm": 80422, "heal": 49914, "dead": 2984, "nowconfirm": 27524, "suspect": 520, "nowsevere": 6416 }, "chinaadd": { "confirm": 120, "heal": 2654, "dead": 38, "nowconfirm": -2572, "suspect": -67, "nowsevere": -390 }, ...........其他数据............. "isshowadd": true } }
3.qt界面的实现
之前的桌面应用程序中,是使用的是qt5版本开发的,qt5自带qjson解析类,而qt 4没有带qjson。为了适配带有qt 4库的板子,我使用了第三方json解析库。这里选择的是小巧的cjson解析库:[cjson download | sourceforge.net](https://sourceforge.net/projects/cjson/) |
如果你的板子是qt 4的库,那么程序不用修改,直接交叉编译运行即可使用。
只包含两个文件:cjson.c和cjson.h,把这两个文件添加到工程里就行了。
整个工程代码也很简单:get接口地址,把接收到的数据保存到本地,调用cjson解析数据文件,把解析出的数据显示,数据文件删除。代码可以到文章末尾开源地址获取。下面介绍几个关键部分代码的实现:
3.1 json数据的解析
//打开保存的json数据文件,并调用解析函数
void dialog::parsedata(qstring filename)
{
qfile file(filename);
if(!file.open(qiodevice::readonly))
{
qdebug() << "file open failed";
return;
}
qbytearray alldata = file.readall();
file.close();
// qdebug() << alldata;
getdata(alldata);
file.remove(); //删除文件
return;
}
//把数据解析出来并显示在标签上
void dialog::getdata(qbytearray str)
{
cjson *ret_obj;
cjson *root_obj;
root_obj = cjson_parse(str); //创建json解析对象,返回json格式是否正确
if (!root_obj)
{
disinfo("json format error");
qdebug() << "json format error";
}
else
{
disinfo("json format ok");
qdebug() << "json format ok";
ret_obj = cjson_getobjectitem(root_obj, "ret");
if(cjson_isnumber(ret_obj))
{
int ret = 1;
ret = ret_obj->valueint;
// qdebug() << ret_obj->valueint;
}
char *data_str = cjson_getobjectitem(root_obj, "data")->valuestring;
cjson *data_obj = cjson_parse(data_str);
if(!data_obj)
{
qdebug() << "data json err";
cnt_error ;
qstring error = "err:" qstring::number(cnt_error);
ui->lbe_error->settext(error);
}
else
{
qdebug() << "data json ok";
char *lastupdatetime = cjson_getobjectitem(data_obj, "lastupdatetime")->valuestring;
qdebug() << lastupdatetime;
ui->lbe_update_time->settext(lastupdatetime);
cjson *chinatotal_obj = cjson_getobjectitem(data_obj, "chinatotal");
int chinatotal_confirm = cjson_getobjectitem(chinatotal_obj, "confirm")->valueint;
int chinatotal_heal = cjson_getobjectitem(chinatotal_obj, "heal")->valueint;
int chinatotal_dead = cjson_getobjectitem(chinatotal_obj, "dead")->valueint;
int chinatotal_nowconfirm = cjson_getobjectitem(chinatotal_obj, "nowconfirm")->valueint;
int chinatotal_suspect = cjson_getobjectitem(chinatotal_obj, "suspect")->valueint;
int chinatotal_nowsevere = cjson_getobjectitem(chinatotal_obj, "nowsevere")->valueint;
ui->lbe_total_confirm->setnum(chinatotal_confirm);
ui->lbe_total_heal->setnum(chinatotal_heal);
ui->lbe_total_dead->setnum(chinatotal_dead);
ui->lbe_total_nowconfirm->setnum(chinatotal_nowconfirm);
ui->lbe_total_suspect->setnum(chinatotal_suspect);
ui->lbe_total_nowsevere->setnum(chinatotal_nowsevere);
cjson *chinaadd_obj = cjson_getobjectitem(data_obj, "chinaadd");
int chinaadd_confirm = cjson_getobjectitem(chinaadd_obj, "confirm")->valueint;
int chinaadd_heal = cjson_getobjectitem(chinaadd_obj, "heal")->valueint;
int chinaadd_dead = cjson_getobjectitem(chinaadd_obj, "dead")->valueint;
int chinaadd_nowconfirm = cjson_getobjectitem(chinaadd_obj, "nowconfirm")->valueint;
int chinaadd_suspect = cjson_getobjectitem(chinaadd_obj, "suspect")->valueint;
int chinaadd_nowsevere = cjson_getobjectitem(chinaadd_obj, "nowsevere")->valueint;
lbedisplay(ui->lbe_add_confirm, chinaadd_confirm);
lbedisplay(ui->lbe_add_heal, chinaadd_heal);
lbedisplay(ui->lbe_add_dead, chinaadd_dead);
lbedisplay(ui->lbe_add_nowconfirm, chinaadd_nowconfirm);
lbedisplay(ui->lbe_add_suspect, chinaadd_suspect);
lbedisplay(ui->lbe_add_nowsevere, chinaadd_nowsevere);
}
// cjson_delete(ret_obj);
// cjson_delete(data_obj);
cjson_delete(root_obj);//释放内存
disinfo("更新完成");
cnt_success ;
qstring success = "ok:" qstring::number(cnt_success);
ui->lbe_success->settext(success);
}
}
//数据的显示
void dialog::lbedisplay(qlabel *lbe, int num)
{
if(num > 0)
lbe->settext(" " qstring::number(num));
else
lbe->settext(qstring::number(num));
}
3.2 获取本地ip地址
//forexample:192.168.1.111
qstring dialog::getlocalmachineip()
{
qstring ipaddress;
qlist ipaddresseslist = qnetworkinterface::alladdresses();
for(qhostaddress &addr : ipaddresseslist)
{
// 找到不是本地ip,并且是ipv4协议,并且不是169开头的第一个地址
if(addr != qhostaddress::localhost && addr.protocol() == qabstractsocket::ipv4protocol && !addr.tostring().startswith("169"))
{
ipaddress = addr.tostring();
break;
}
}
// if we did not find one, use ipv4 localhost
if (ipaddress.isempty())
ipaddress = qhostaddress(qhostaddress::localhost).tostring();
return ipaddress;
}
桌面linux版本的运行效果:
4.在开发板上运行qt程序
如果在桌面运行正常,就可以使用ya157c构建套件来编译工程,生成可以在开发板上运行的程序,然后使用scp命令传输到开发板上。
#使用网线把开发板连接上路由器
#使用udhcpc自动获取ip地址
udhcpc
#查看获取到的ip地址
ifconfig
#确认连接到互联网
ping www.baidu.com
#如果有回复数据,说明已经成功连接上互联网
#使用scp命令或共享目录的方式把可执行文件传输到开发板上
scp qte_2019_ncov root@192.168.1.109:/home/root
#执行程序
./qte_2019_ncov
最终效果
这个版本是上一个版本的,右上角没有显示开发板的ip地址和成功失败次数统计,最新版本的程序中已经添加了这个功能。
桌面linux版效果:
5.使用无线模块联网
ya157c开发板已经板载了一个wifi & 蓝牙模组——ap6212,可以直接连接无线网,这样就不需要使用网线的方式联网了。
#关闭eth0
ifconfig eth0 down
#启用wlan0
rfkill unblock wifi
ifconfig wlan0 up
#在当前文件夹生成wifi配置文件
wpa_passphrase "m6_note" "qwert125" > wifi.conf
#查看生成的wifi配置信息
cat wifi.conf
#加载wifi配置文件
wpa_supplicant -b -c wifi.conf -i wlan0
#扫描附近的wifi信息
iw dev wlan0 scan | grep ssid
#自动获取ip地址
udhcpc -i wlan0
#设置dns
echo "nameserver 114.114.114.114" > /etc/resolv.conf
#连接互联网
iw wlan0 link
#测试网络连接
ping www.wangchaochao.top
为了方便快捷的连接wifi,可以把以上命令写成一个shell脚本,需要连接wifi时,直接执行这个脚本就可以了。先在本地生成wifi配置信息:
connect_wifi.sh脚本文件内容:
#!/bin/bash
wf_ssid="m6_note"
wf_password="qwert125"
#关闭eth0
ifconfig eth0 down
#使能wlan0
rfkill unblock wifi
ifconfig wlan0 up
#输出wifi信息
echo "wifi_ssid:$wf_ssid"
echo "wifi_password:$wf_password"
#在当前文件夹生成wifi配置信息
wpa_passphrase $wf_ssid $wf_password > $wf_ssid.conf
#加载wifi配置文件
wpa_supplicant -b -c /home/root/$wf_ssid.conf -i wlan0
#扫描附近的wifi
iw dev wlan0 scan | grep ssid
#自动获取ip地址
udhcpc -i wlan0
#配置dns
echo "nameserver 114.114.114.114" > /etc/resolv.conf
#连接网络
iw wlan0 link echo "wifi连接成功"
wifi账号和密码修改一下,就可以直接使用了。
6.代码下载
整个qt工程代码已经开源在github,qt4/qt5兼容。如果下载速度很慢,可以选择国内的gitee速度会快很多。
#github
https://github.com/whik/qte_2019_ncov
#gitee
https://gitee.com/whik/qte_2019_ncov
目前界面还比较简单,7寸的显示屏可以显示很多内容,之后会尽量完善界面信息,欢迎大家关注!
本文来自金沙js1005线路-js555888金沙老品牌科技,原文地址:
http://www.myir-tech.com/resource/540.asp,转载请注明出处。