前言

最近在学习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用户点击状态的获取。通过这个功能的实现思路,我们也可以把软件上的一些文本和图片,通过远程来及时更新,如二维码等等。

历史精选


欢迎大家关注我的个人博客

或微信扫码关注我的公众号

Qt实现软件自动更新的一种简单方法的更多相关文章

  1. Android - 软件自动更新的实现

    转自:http://blog.csdn.net/wwj_748/article/details/8195565 接触到一个很实用的技术,那就是软件自动更新.一般开发者是通过自行在应用平台添加更新版本的 ...

  2. 代码操作Word时,目录自动更新的两种方法

    最近的项目中有一个功能点为:根据分析数据库并生成报告.不过不是大数据.数据挖掘之类,报告的内容.组织方式都是事先固定下来的.实现的方式为,在普通word文档中插入书签制成模板,然后程序使用OpenXM ...

  3. ssh自动登录的4种实现方法

    ssh自动登录的几种实现方法,记录在此.  1. 自动ssh/scp方法 A为本地主机(即用于控制其他主机的机器) ; B为远程主机(即被控制的机器Server), 假如ip为192.168.60.1 ...

  4. 使用strace工具故障排查的5种简单方法

    使用strace工具故障排查的5种简单方法 本文源自5 simple ways to troubleshoot using strace strace 是一个非常简单的工具,用来跟踪可执行程序的系统调 ...

  5. WPF编程 ,TextBlock 显示百分数值的一种简单方法。

    原文:WPF编程 ,TextBlock 显示百分数值的一种简单方法. 版权声明:我不生产代码,我只是代码的搬运工. https://blog.csdn.net/qq_43307934/article/ ...

  6. .net winform软件自动更新

    转载自 http://dotnet.chinaitlab.com/DotNetFramework/914178.html 关于.NET windows软件实现自动更新,本人今天写了一个DEMO,供大家 ...

  7. 实现Django ORM admin view中model字段choices取值自动更新的一种方法

    有两个表,一个是记录网站信息的site表,结构如下: CREATE TABLE `site` ( `id` ) unsigned NOT NULL AUTO_INCREMENT, `name` ) N ...

  8. 如何屏蔽 iOS 软件自动更新,去除更新通知和标记

    适用于 iOS.iPadOS 和 watchOS,即 iPhone.iPad 和 Apple Watch 通用. 请访问原文链接:https://sysin.org/article/Disable-i ...

  9. Android 软件自动更新功能实现的方法

    相信所有的用户都遇到过软件提醒更新的情况,下面就将实现此功能 首先看一下程序目录结构 步骤: 1.新建一个类UpdateManger,用于显示提示更新 详细出处参考:http://www.jb51.n ...

随机推荐

  1. python网络编程:socket、服务端、客户端

    本文内容: socket介绍 TCP: 服务端 客户端 UDP: 服务端 客户端 首发时间:2018-02-08 01:14 修改: 2018-03-20 :重置了布局,增加了UDP 什么是socke ...

  2. 前端限制input输入框(只能输入正整数)

    <input onkeyup="if(this.value.length==1){this.value=this.value.replace(/[^1-9]/g,'')}else{th ...

  3. sysfs文件系统的建立【转】

    http://blog.csdn.net/dndxhej/article/details/7434615 对sysfs和设备模型有了解的都会知道sysfs实际是为了将设备模型导出到用户空间的一个内存文 ...

  4. 使用虚拟环境virtualenv/Virtualenvwrapper隔离多个python

    virtualenv 系统中的多个python混用会导致$PYTHONPATH混乱,或者各个工程对于package的版本要求不同等等情况.有一个简单的解决方案就是用virtualenv来隔离多个pyt ...

  5. vsftpd不支持目录软链接的解决办法

    vsftpd本身不支持软连接,而在用FTP共享的时候又不想移动文件位置,便在网上找到了一个workaround: Linux内核从2..0开始支持把一部分文件系统挂载到文件系统中的其他位置,mount ...

  6. PLS-00306: 调用 'SYNCRN' 时参数个数或类型错误

    System.Data.OracleClient.OracleException (0x80131938): ORA-00604: 递归 SQL 级别 1 出现错误 ORA-06550: 第 1 行, ...

  7. Beta冲刺(4/5)(麻瓜制造者)

    今日已完成 邓弘立:完成了商品管理(下架)和搜索功能 符天愉:完成了后台管理员界面的登录和其他视图的载入 江郑:昨天来决定跨域执行请求,后台参考一些意见以后,操作起来没有那么容易实现,和队友交流以后本 ...

  8. Beta阶段总结博客(麻瓜制造者)

    Beta冲刺过程中各个成员的贡献百分比: 成员 贡献值 邓弘立 15% 符天愉 14% 江郑 14% 刘双玉 14% 肖小强 13% 李佳铭 11% 汪志彬 11% 伍杰麟 8% 项目的发布说明 本版 ...

  9. Python3编写网络爬虫09-数据存储方式二-JSON文件存储

    2.JSON文件存储 全称为JavaScript Object Notation 通过对象和数组的组合来表示数据,构造简洁且结构化程度非常高.是一种轻量级的数据交换格式 2.1 对象和数组 在Java ...

  10. 线程间的通信_多生产者多消费者问题_JDK1.5新特性_Lock

    对于同步代码块,对于锁的操作是隐式的但是在JDK1.5之前的这种方法效率有点低,判断会很多,后面升级之后有新的解决方案 jdk1.5以后将同步和锁封装成了对象,并将操作锁的隐式方式定义到了该对象中,将 ...