iMX287A基於嵌入式Qt的新冠肺炎疫情監控平臺
阿新 • • 發佈:2020-03-05
@[toc]
### 1.前言
之前我使用在桌面版本Qt實現了肺炎疫情監控平臺:[基於Qt的新冠肺炎疫情資料實時監控平臺(開源小專案)](https://www.cnblogs.com/whik/p/12304719.html)。既然Qt是跨平臺的,正好手裡有一塊iMX287A的開發套件,含一塊4.3寸的顯示屏,那麼能不能在嵌入式平臺實現一下呢?
最後實現的效果:![](https://img-blog.csdnimg.cn/20200305104815590.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3doaWsxMTk0,size_16,color_FFFFFF,t_70)
### 2.資料介面的獲取
疫情監控平臺的實現,簡單的說,就是資料的展示,而資料從哪裡來呢?現在很多網際網路公司都做了自己的疫情監控平臺,我這裡採用的是騰訊新聞的資料來源,資料內容比較豐富,也比較穩定。
資料來源:[實時更新:新冠肺炎疫情最新動態](https://news.qq.com/zt2020/page/feiyan.htm#/)
介面地址的獲取方法可以參考:[基於Qt的新冠肺炎疫情資料實時監控平臺(開源小專案)](https://www.cnblogs.com/whik/p/12304719.html)
如果把所有的資料放在一個接口裡,資料量會很大,騰訊把資料分成了幾個介面
```shell
#包含最新疫情資料、各省市最新資料、其他國家最新資料
https://view.inews.qq.com/g2/getOnsInfo?name=disease_h5
#包含歷史資料d
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
```
由於液晶螢幕太小,只有4.3寸,解析度也比較低480 × 272,顯示不了太多的內容,所以我們只使用到了`https://view.inews.qq.com/g2/getOnsInfo?name=disease_h5`這個介面中的`chinaTotal`和`chinaAdd`這兩組資料。
這個介面包括很多資料,全國累計和新增的最新資料,各省市其他國家的最新資料等等。檔案大小大概在160KB。
資料格式:
```json
{
"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,所以只能使用第三方JSON解析庫,我這裡選擇的小巧的cJSON解析庫:[cJSON download | SourceForge.net](https://sourceforge.net/projects/cjson/)
只包含兩個檔案:cJSON.c和cJSON.h,把這兩個檔案新增到工程裡就行了。
程式碼也很簡單:GET介面地址,把接收到的資料儲存到本地,呼叫cJSON解析資料檔案,把解析出的資料顯示,資料檔案刪除。程式碼可以到文章末尾開源地址獲取。下面介紹一個幾個關鍵部分程式碼的實現:
#### 3.1 JSON資料的解析
```cpp
//開啟儲存的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 根據編譯器的版本自動調整視窗大小
```cpp
void Dialog::setLocation()
{
const QRect availableSize = QApplication::desktop()->availableGeometry(this);
qint32 DESKTOP_QT4 = 264199;
qint32 DESKTOP_QT5 = 329728;
qint32 ARM_IMX287 = 263939;
qint32 ARM_YA157C = 264199;
//output current qt version id
qDebug() << QT_VERSION;
//output curretn screen resolution ratio
qint16 width = availableSize.width();
qint16 height = availableSize.height();
qDebug() << "width: " << width << "height:" << height;
if(QT_VERSION == ARM_IMX287)
this->resize(width-5, height-15);
else
this->resize(width/3, height/3);
qint16 loc_width = this->width();
qint16 loc_height = this->height();
qint16 loc_x = (width - loc_width) / 2;
qint16 loc_y = (height - loc_height) / 2;
qDebug() << "locx:" << loc_x << "locy" << loc_y;
if(QT_VERSION == ARM_IMX287)
this->move(0, 0);
else
this->move(loc_x, loc_y);
}
```
#### 3.3 獲取本地IP地址
```cpp
//forexamle:192.168.1.111
QString Dialog::GetLocalmachineIP()
{
QString ipAddress;