前言
最近在學習Qt開發上位機,想實現一個檢查更新的功能,網上搜索了一大圈,發現實現過程都很復雜,關鍵是代碼看不懂,所以就自己開發一種簡單的方式來實現。實現效果如下:
點擊“檢查更新”按鈕,如果當前版本低於遠程的版本,那么會彈出如下窗口,提示更新,並顯示遠程的的版本號,更新時間,更新說明,如下圖所示:

如果點擊"去下載",那么會調用系統默認瀏覽器,直接創建下載任務。點擊"不更新",則取消更新。
如果當前版本號和遠程一致,那么會提示"已經是最新版本":

實現原理
首先在遠程放置了一個文件,內容包含最新版軟件的版本號、下載鏈接、更新時間、更新說明等,當用戶點擊"檢查更新"時,會訪問這個文件的地址,並對文件內容進行解析,得到最新的版本號、下載鏈接、更新時間、更新說明等,如果版本號比當前軟件的版本號高,那么彈出更新窗口。
我們先創建一個文本文件,可以是TXT格式、XML格式、JSON格式等等,因為之前學習過JSON的解析,所以這里我選擇了JSON格式,當然選擇其他格式也都是可以的。命名為software_update.json,內容如下:
{
"PulseSensor":
{
"LatestVerison":"V1.1",
"Url":"https://www.demo.com/Demo_v1.1.exe",
"UpdateTime":"2019-03-31",
"ReleaseNote":"\n1.添加檢查更新說明,包含版本號,下載鏈接,更新時間,更新說明.\n2.優化“關於”界面"
},
"RGBContrl":
{
"LatestVerison":"V1.0",
"Url":"https://www.demo.com/Demo_v1.1.exe",
"UpdateTime":"2019-03-30",
"ReleaseNote":"版本說明"
}
}
其中Url鍵值,是最新版軟件的下載地址,然后把這個文件存放到服務器上,可以通過鏈接直接訪問, 如:https://www.demo.com/software_update.json,如果有軟件發布,只需要修改這個文件的內容:版本號、下載鏈接、更新說明、更新時間。當然,從文件內容也可以看出,支持多個軟件的說明放在一起。
Qt端的實現
Qt端的實現,主要使用到了網絡請求和JSON解析兩個部分。
1.pro文件添加網絡支持
# 網絡請求
QT += network
2.添加頭文件
//網絡相關頭文件
#include <QtNetwork/QNetworkAccessManager>
#include <QtNetwork/QNetworkRequest>
#include <QtNetwork/QNetworkReply>
//JSON相關頭文件
#include <QJsonDocument>
#include <QJsonObject>
#include <QJsonArray>
3.對象的定義和函數的聲明
QNetworkAccessManager *manager; //定義網絡請求對象
int parse_UpdateJSON(QString str); //解析數據函數的聲明
void replyFinished(QNetworkReply *reply); //網絡數據接收完成槽函數的聲明
QString CurVerison = "V1.1"; //定義當前軟件的版本號
4.連接信號與槽
manager = new QNetworkAccessManager(this); //新建QNetworkAccessManager對象
connect(manager, SIGNAL(finished(QNetworkReply*)), this, SLOT(replyFinished(QNetworkReply*)));//關聯信號和槽
5.更新按鈕槽函數的實現
當點擊"檢查更新"按鈕,會發送一個網絡請求,即上面的JSON文件的地址。
void Pulse::on_btn_chkUpdate_clicked()
{
QNetworkRequest quest;
quest.setUrl(QUrl("https://www.demo.com/software_update.json")); //包含最新版本軟件的下載地址
quest.setHeader(QNetworkRequest::UserAgentHeader,"RT-Thread ART");
manager->get(quest); //發送get網絡請求
}
6.接收完成槽函數的實現
如果數據接收完成,那么會執行這個槽函數,函數里可以把接收的數據保存到文件,或者直接進行解析,由於數據量較小,這里選擇了直接進行解析。
void Pulse::replyFinished(QNetworkReply *reply)
{
QString str = reply->readAll();//讀取接收到的數據
// qDebug() << str;
parse_UpdateJSON(str);
//文件保存到本地
/*
QFile file("software_update.json");
if(!file.open(QIODevice::WriteOnly | QIODevice::Text)) //append 內容追加在文件后面
{
QMessageBox::critical(this, "錯誤", "文件打開失敗,信息未寫入", "確定");
return;
}
QTextStream out(&file);
out << str; //輸出到文件
file.close(); //關閉文件
qDebug() << "文件保存成功!";
// file.remove();
// qDebug() << "文件已經刪除";
*/
reply->deleteLater(); //銷毀請求對象
}
7.JSON文件的解析
這個函數就是檢查更新功能實現的核心了,對接收到的JSON數據進行解析,並彈出窗口,根據用戶點擊的按鈕,執行對應的操作。
int Pulse::parse_UpdateJSON(QString str)
{
// QMessageBox msgBox;
QJsonParseError err_rpt;
QJsonDocument root_Doc = QJsonDocument::fromJson(str.toUtf8(),&err_rpt);//字符串格式化為JSON
if(err_rpt.error != QJsonParseError::NoError)
{
// qDebug() << "root格式錯誤";
QMessageBox::critical(this, "檢查失敗", "服務器地址錯誤或JSON格式錯誤!");
return -1;
}
if(root_Doc.isObject())
{
QJsonObject root_Obj = root_Doc.object(); //創建JSON對象,不是字符串
QJsonObject PulseValue = root_Obj.value("PulseSensor").toObject();
QString Verison = PulseValue.value("LatestVerison").toString(); //V1.0
QString Url = PulseValue.value("Url").toString(); //https://wcc-blog.oss-cn-beijing.aliyuncs.com/QtUpdate/uFun_Pulse_v1.0.exe
QString UpdateTime = PulseValue.value("UpdateTime").toString();
QString ReleaseNote = PulseValue.value("ReleaseNote").toString();
if(Verison > CurVerison)
{
QString warningStr = "檢測到新版本!\n版本號:" + Verison + "\n" + "更新時間:" + UpdateTime + "\n" + "更新說明:" + ReleaseNote;
int ret = QMessageBox::warning(this, "檢查更新", warningStr, "去下載", "不更新");
if(ret == 0) //點擊更新
{
QDesktopServices::openUrl(QUrl(Url));
}
}
else
QMessageBox::information(this, "檢查更新", "當前已經是最新版本!");
}
return 0;
}
總結
這樣,如果以后有新版本軟件發布,只需要更改遠程文件的內容就行了。這個功能的實現主要用到了網絡文件的讀取,JSON的解析和QMessageBox用戶點擊狀態的獲取。通過這個功能的實現思路,我們也可以把軟件上的一些文本和圖片,通過遠程來及時更新,如二維碼等等。
歷史精選
- JSON簡介
- 使用cJSON庫解析JSON
- 基於uFUN開發板的心率計(一)DMA方式獲取傳感器數據
- 【UFUN開發板評測】小巧而不失精致,簡單而不失內涵——uFun開發板開箱爆照
- 如何使用串口來給STM32下載程序
- STM32串口打印輸出亂碼的解決辦法
- Keil報錯:cannot open source input file "core_cmInstr.h" 解決辦法
歡迎大家關注我的個人博客
或微信掃碼關注我的公眾號

