QML 从无到有 3 (自动更新)
新的需求出来啦,需要自动更新功能,不怕程序升级了。
自动更新,QML不好写,需要c++来辅助,这里就涉及QML中调用c++功能(这里就不写了,百度一下,很多)。
思路:获取版本》下载程序》安装程序
第一步,获取版本信息,可以通过XMLHttpRequest获取最新版本。
第二步,下载程序,通过Qt c++的QtNetwork:
头文件:
#ifndef ZRDOWNLOAD_H
#define ZRDOWNLOAD_H #include <QObject>
#include <QtNetwork/QNetworkAccessManager>
#include <QFile>
#include <QtNetwork/QNetworkReply>
#include <QtNetwork/QNetworkRequest>
#include <QIODevice> class ZRDownload : public QObject
{
Q_OBJECT
Q_PROPERTY(QString url READ GetUrl WRITE SetUrl)
Q_PROPERTY(QString fileName READ GetFileName WRITE SetFileName)
public:
explicit ZRDownload(QObject *parent = );
~ZRDownload(); QString GetUrl();
void SetUrl(QString u);
QString GetFileName();
void SetFileName(QString fn);
private:
QString url;
QString fileName;
QFile *file;
QNetworkAccessManager *accessManager;
QNetworkRequest request;
QNetworkReply *reply; signals:
void progressPosition(double pre); //更新进度条信号
void downloadFinished(); //结束信号 protected slots:
void httpDownload();
void replyFinished(QNetworkReply*reply);
void onDownloadProgress(qint64 bytesSent,qint64 bytesTotal);
void onReadyRead();
}; #endif // ZRDOWNLOAD_H
CPP文件:
#include "zrdownload.h"
#include <QDebug> ZRDownload::ZRDownload(QObject *parent) : QObject(parent)
{
accessManager = NULL;
reply = NULL;
}
ZRDownload::~ZRDownload()
{
} QString ZRDownload::GetUrl()
{
return url;
} void ZRDownload::SetUrl(QString u)
{
url = u;
} QString ZRDownload::GetFileName()
{
return fileName;
} void ZRDownload::SetFileName(QString fn)
{
fileName = fn;
} void ZRDownload::httpDownload(){ file=new QFile(fileName);
bool suc = file->open(QIODevice::WriteOnly);//只读方式打开文件 accessManager=new QNetworkAccessManager(this); request.setUrl(url); /******************设置http的header***********************/
// request.setHeader(QNetworkRequest::ContentTypeHeader, "multipart/form-data");
// request.setHeader(QNetworkRequest::ContentTypeHeader, "application/octet-stream");
// request.setRawHeader("Content-Disposition","form-data;name='doc';filename='a.txt'");
//request.setHeader(QNetworkRequest::ContentLengthHeader,post_data.length()); reply=accessManager->get(request);//通过发送数据,返回值保存在reply指针里.
connect(accessManager, SIGNAL(finished(QNetworkReply*)), this, SLOT(replyFinished(QNetworkReply*)));//finish为manager自带的信号,replyFinished是自定义的
connect(reply, SIGNAL(downloadProgress(qint64,qint64)), this, SLOT( onDownloadProgress(qint64 ,qint64 )));//download文件时进度
connect((QObject *)reply, SIGNAL(readyRead()),this, SLOT(onReadyRead())); }
/***************响应结束**************************/
void ZRDownload::replyFinished(QNetworkReply *reply){
//获取响应的信息,状态码为200表示正常
QVariant status_code = reply->attribute(QNetworkRequest::HttpStatusCodeAttribute);
QByteArray bytes = reply->readAll(); //获取字节
QString result(bytes); //转化为字符串 //无错误返回
if(reply->error() == QNetworkReply::NoError)
{
QByteArray bytes = reply->readAll(); //获取字节
QString result(bytes); //转化为字符串 file->flush();
file->close();
delete file;
file=NULL;
}
else
{
//处理错误
} reply->deleteLater();//要删除reply,但是不能在repyfinished里直接delete,要调用deletelater;
reply=NULL; accessManager->deleteLater();
accessManager=NULL; downloadFinished();
} /***********更新进度条*************/
void ZRDownload::onDownloadProgress(qint64 bytesSent, qint64 bytesTotal){ double pre = double(bytesSent)/bytesTotal; progressPosition(pre);
} void ZRDownload::onReadyRead(){ file->write(reply->readAll());
}
上面的代码也是修改网上的代码,增加了QML调用的信息。
注意:项目文件pro中需要添加 QT += network
main.cpp:
添加 qmlRegisterType<ZRDownload>("xxx.xxx.ZRDownload", 1, 0, "ZRDownload");
QML调用:
ZRDownload{
id:download
url:"http://xxx.xxx.com/xx.apk"
fileName:""
onProgressPosition:progressBar.update(pre) //自定义更新进度条函数
onDownloadFinished: {
//下载完成
}
} //启动下载
download.fileName=getAppPath();//设置保存目录,pc和安卓不同
download.httpDownload();
第三步,安装程序:
不同平台,安装程序的代码也不同,PC平台使用QProcess启动安装程序,安卓平台通过QAndroidJniObject调用Activity实现。下面是代码:
#ifndef ZRINSTALL_H
#define ZRINSTALL_H #include <QObject>
#include <QString> class ZRInstall : public QObject
{
Q_OBJECT
Q_PROPERTY(QString fileName WRITE SetFileName)
public:
explicit ZRInstall(QObject *parent = ); void SetFileName(QString fn);
signals: public slots:
void install();
private:
QString m_FileName;
}; #endif // ZRINSTALL_H
头文件
#include "zrinstall.h"
#include <QDebug>
#if defined(Q_OS_ANDROID)
#include <QtAndroid>
#else
#include <QProcess>
#endif ZRInstall::ZRInstall(QObject *parent) : QObject(parent)
{ } void ZRInstall::SetFileName(QString fn)
{
m_FileName = fn;
} void ZRInstall::install()
{
#if defined(Q_OS_ANDROID)
//安装apk
QAndroidJniObject path = QAndroidJniObject::fromString("file://"+m_FileName);
QAndroidJniObject uri = QAndroidJniObject::callStaticObjectMethod("android/net/Uri", "parse", "(Ljava/lang/String;)Landroid/net/Uri;", path.object<jstring>());
QAndroidJniObject param = QAndroidJniObject::getStaticObjectField<jstring>("android/content/Intent", "ACTION_VIEW");
QAndroidJniObject intent("android/content/Intent","(Ljava/lang/String;)V",param.object<jstring>());
QAndroidJniObject type = QAndroidJniObject::fromString("application/vnd.android.package-archive");
QAndroidJniObject result = intent.callObjectMethod("setDataAndTypeAndNormalize", "(Landroid/net/Uri;Ljava/lang/String;)Landroid/content/Intent;", uri.object<jobject>(), type.object<jstring>());
QtAndroid::startActivity(intent, , );
#else
//qDebug()<<m_FileName;
QProcess * proc = new QProcess();
proc->startDetached(m_FileName,QStringList());
delete proc;
#endif
}
CPP文件
android{
QT += androidextras
}
项目文件pro
调用就不写了,可以参考上面download。
这样整个版本自动更新就写好了,有一些细节自己需要注意,如下载安装文件不同,安装目录不同。
QML 从无到有 3 (自动更新)的更多相关文章
- 解析大型.NET ERP系统 自动更新
C/S架构的应用程序需要支持自动更新功能,当新版本程序发布后,正在运行的客户端能检测到新版本的程序,通知用户是否下载更新.工作以来参与过几个自动更新模块的设计与维护,撰文总结自动更新模块设计与实现. ...
- 扩展BindingList,防止增加、删除项时自动更新界面而不出现“跨线程操作界面控件 corss thread operation”异常
在做界面程序时,常常需要一些数据类,界面元素通过绑定等方式显示出数据,然而由于UI线程不是线程安全的,一般都需要通过Invoke等方式来调用界面控件.但对于数据绑定bindingList而言,没法响应 ...
- 分析nuget源码,用nuget + nuget.server实现winform程序的自动更新
源起 (个人理解)包管理最开始应该是从java平台下的maven开始吧,因为java的开发大多数是基于开源组件开发的,一个开源包在使用时很可能要去依赖其他的开源包,而且必须是特定的版本才可以.以往在找 ...
- ClickOnce部署(2):自动更新
上次我们说了如何用最基本的方式用ClickOnce技术部署应用程序项目,本篇我们来认识一下如何让应用程序具备自动更新的功能. 我们依然通过实例来学习. 第一步,随便建一个应用程序项目,至于是控制台.W ...
- Android接入百度自动更新SDK
一:前言 公司的app,上传到百度应用市场,然后说必须要接入百度的自动更新sdk才能上架,于是从百度官网上去下载jar包,下载的时候必须要带上数据统计,如果使用自动的jar包,还需要带上广告联盟,坑爹 ...
- C#之tcp自动更新程序
.NETTCP自动更新程序有如下几步骤: 第一步:服务端开启监听 ServiceHost host; private void button1_Click(object sender, EventAr ...
- 使用 SVN Hook 实现服务器端代码自动更新
之前的做法是客户端提交代码之后,再去服务器端项目中 svn up 一下来更新代码,让服务器端的项目更新到最新版本.可以编写一个 post-commit 钩子脚本来实现服务器端代码的自动更新,它在 SV ...
- git 远程版本库,github提供服务原理,git自动更新发送邮件
1.安装好Linux,安装好Git(192.168.1.239) 2.创建一个用户zph(让此用户提供git on server),密码设置为12345678 # useradd zph # pass ...
- 【原创】我所理解的自动更新-APP发布与后台发布
发布后台 创建渠道:添加新的渠道,设置渠道名称,自动生成渠道id. 查看渠道:查看渠道基本信息,渠道app版本号,资源版本号,是否开启更新. 创建/更新APP:选择打包ios,androi ...
随机推荐
- 易用BPM时代,软件开发者缘何选择H3?
近年来,企业级软件开发市场暗流汹涌,呈现出多种态势.软件开发团队规模趋于小型化,工作方式趋于快捷化,超过半数的软件开发者在工作中会选择使用易用的软件开发工具.随着流程管理越来越受到企业的重视,流程开发 ...
- 【转】Android开发中让你省时省力的方法、类、接口
转载 http://www.toutiao.com/i6362292864885457410/?tt_from=mobile_qq&utm_campaign=client_share& ...
- ubuntu14 查找并删除所有文件名中带有特定关键词的文件
http://askubuntu.com/questions/625219/how-to-search-and-delete-files-who-contain-specific-string-in- ...
- tg2015 信息传递 (洛谷p2661)
题目描述 有n个同学(编号为1到n)正在玩一个信息传递的游戏.在游戏里每人都有一个固定的信息传递对象,其中,编号为i的同学的信息传递对象是编号为Ti同学. 游戏开始时,每人都只知道自己的生日.之后每一 ...
- 架构之路(九)Session Per Request
前面的两篇反应很差:没评论没赞.很伤心啊,为什么呢?搞得我好长一段时间都没更新了——呵呵,好吧,我承认,这只是我的借口.不过,还是希望大家多给反馈.没有反馈,我就只能猜了:前面两篇是不是写得太“粗”了 ...
- ReactNative&weex&DeviceOne对比
React Native出来有一段时间了,国内的weex和deviceone是近期发布的,我可以说从2011年就开始关注快速开发的跨平台平台技术了,接触过phoneGap.数字天堂.appcan等早期 ...
- -Dmaven.multiModuleProjectDirectory system property is not set. Check $M2_HO 解决办法
最近在使用maven,项目测试的时候出现了这么一个错.-Dmaven.multiModuleProjectDirectory system property is not set. Check $M2 ...
- (转载)解决“Windows Update一直无法完成”的方法
近日彻底重装系统,启动Win7的"Windows Update",程序显示在检查更新,却一直没有结果. 在排除网络问题,排除杀毒软件和防火墙的问题之后,感觉还是程序或者配置除了问题 ...
- 2.Kali安装VMware tools(详细+异常处理)
dnt@MT:~$ cd /media/cdrom0 进入光驱内 dnt@MT:/media/cdrom0$ ls 查看当前目录下有哪些内容manifest.txt run_upgrader.sh V ...
- JS中 call() 与apply 方法
1.方法定义 call方法: 语法:call([thisObj[,arg1[, arg2[, [,.argN]]]]]) 定义:调用一个对象的一个方法,以另一个对象替换当前对象. 说明: call ...