Qt实现软件自动更新的一种简单方法

前言

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

历史精选



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

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

原文地址:https://www.cnblogs.com/whik/p/10630902.html

时间: 2024-10-14 06:16:14

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

Android - 软件自动更新的实现(转)

在客户端实现更新操作 涉及到三个技术: 1.xml文件的解析 2.HttpURLConnection连接 3.文件流I/O 这里创建一个解析xml文件的服务类:ParXmlService.java [java] view plaincopy package com.xiaowu.news.update; import java.io.InputStream; import java.util.HashMap; import javax.xml.parsers.DocumentBuilder; i

延缓或阻止Windows 10软件自动更新教程

Windows10强制自动更新机制从"诞生"之际就褒贬不一,强制更新之后从一定程度上提高了系统的安全性,然而它同时也会给用户带来许多不可预料的麻烦,比如说前一段时间的无限重启.那么我们能不能阻止软件自动更新呢?答案当然是肯定的.  如果你使用的是Win10专业版,可以通过设置来推迟升级,具体操作方法如下:  打开开始菜单,然后依次打开"设置"--"更新和安全",然后点击"高级选项",选择"推迟升级"即可. 

Android - 软件自动更新的实现

转自:http://blog.csdn.net/wwj_748/article/details/8195565 接触到一个很实用的技术,那就是软件自动更新.一般开发者是通过自行在应用平台添加更新版本的apk.这样做,如果是在一两个应用平台发布应用,那还说得过去,工作量还不是很大.但大家都知道,Android开发者是比较苦逼的.由于开源所致,出现了N多应用市场.如果想赚取更多的收入,那就要在各个应用市场进行更新.那就悲催咯. 比较出名的一些应用市场有如下: 那如何实现软件自动更新,下面是具体实例:

元素水平居中和垂直居中的几种简单方法

一.如何使元素在水平方向上居中 1. 使用text-align:center. 在父级元素的CSS样式设置text-align:center.把内部嵌套一个div把它当作文本来对待,不过这个方法有时候是不管用的. 2.在需要居中的元素设置margin:0 auto.     这句CSS的意思为:设置margin-left和margin-right为自动适应父级元素宽度.所以可以使元素水平居中,不过记得设置其width. 二.如何使元素在垂直方向上居中 1.使图片在垂直方向上居中. div{bac

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

原文:WPF编程 ,TextBlock 显示百分数值的一种简单方法. 版权声明:我不生产代码,我只是代码的搬运工. https://blog.csdn.net/qq_43307934/article/details/86524376 此处是绑定了另一控件的值,也可用于数据绑定的情况,最后格式化一句是关键,? <TextBlock Text="{Binding Value,Mode=OneWay,ElementName=pro2,StringFormat={}{0:p2}}" /&

android软件自动更新的实现步骤

本篇文章是直接下载最新的APK安装的方法,并不是增量下载该APk. 转载请注明出处:http://blog.csdn.net/harryweasley/article/details/44955719,谢谢 想要实现一个android应用,自动更新下载APK软件的方法,我采取的是以下几步方法: 1.每次进入主界面时,获取服务器的数据,看是否是最新版本,是,则无操作,否,则进行以下步骤: 2.弹出是否更新软件的对话框,点击下载后 3.弹出下载的进度条的对话框,开始下载,可以上随时点击按钮,停止下载

.net 签名加密实现的一种简单方法

加密方法有很多,以下是其中一种简单的签名模式 1.首先客户端通过webapi按照IP地址,时间戳,随机数生成签名,并传递序列号 private Result_Sign Valid()        {            string ServerIP = "192.168.1.6";// HttpContext.Request.ServerVariables.Get("Local_Addr").ToString(); //地址            string

Python库安装的三种简单方法

我使用的是python3.4 第一种: pip3 install 库名 pip install 库名 第二种:http://www.lfd.uci.edu/~gohlke/pythonlibs/ 下载对应文件的whl,然后直接这样就可以了 第三种,到各种库官方地址下载源代码 转到文件对应目录,直接命令下 python setup.py install 关于三种安装方法,可能用cx-Freeze打包后,程序会缺库,建议把主要的源代码扔到Lib\site-packages下

Android软件自动更新(自定义处理,不使用第三方)

来源:http://www.android100.org/html/201406/08/21956.html XML放入网络空间---version.xml .url地址应该为正常***/*****.apk<update> <version>5</version> <name>yuanbao</name> <url>http://cdn.market.hiapk.com/data/upload//2012/06_27/13/yuanb