python+qt实现CS端软件自动更新的功能

公司业务基本都是CS端软件,有时候需要升级软件的时候需要客户把设备寄回公司来才能完成升级,感觉很不方便。前段时间公司做了个support技术支持的网站,因此想做个在线升级的软件,通过可视化界面(qt)和python下载上传到网站上的文件,来完成自动更新升级的功能。

一、python基于http协议下载文件

python下载网站上的文件有多种方法,这里采用requests的库,通过一些逻辑实现断点续传下载。

#!/usr/bin/python3
import sys
import requests
import os
#消除requests的verrify=false时的警告
requests.packages.urllib3.disable_warnings()
def downfile(url,file_path):
    r1=requests.get(url,stream=True,verify=False)
    total_size=int(r1.headers['Content-Length'])
    if(os.path.exists(file_path)):
        temp_size=os.path.getsize(file_path)
    else:
        temp_size=0;
    print(temp_size,total_size)
    #设置range和下方的chunk_size实现断点续传功能
    headers={'Range':'bytes=%d-'%temp_size}
    r=requests.get(url,stream=True,verify=False,headers=headers)
    with open(file_path,'ab+') as f:
        for chunk in r.iter_content(chunk_size=1024):
            if chunk:
                temp_size+=len(chunk)
                f.write(chunk)
                f.flush()                   
                done=int(50*temp_size/total_size)
                sys.stdout.write("\r[%s%s]%d%%"%('*'*done,' '*(50-done),100*temp_size/total_size))
                sys.stdout.flush()
    print()

if __name__=='__main__':
    link=r'http://你的网址'
    UUID=r'你的文件.zip'
    path="你的文件夹/my.zip"
    url=os.path.join(link,UUID)
    downfile(url,path)

requests.get参数解释:当下载大的文件的时候,建议使用stream模式。默认情况下是false,他会立即开始下载文件并存放到内存当中,倘若文件过大就会导致内存不足的情况。

当把get函数的stream参数设置成True时,它不会立即开始下载,当你使用iter_content或iter_lines遍历内容或访问内容属性时才开始下载。需要注意一点:文件没有下载之前,它也需要保持连接。

  • iter_content:一块一块的遍历要下载的内容
  • iter_lines:一行一行的遍历要下载的内容

使用上面两个函数下载大文件可以防止占用过多的内存,因为每次只下载小部分数据。

示例代码如上图代码中的for循环。

最终结果(*号是进度):

二、qt调用python

qt有友好的人机交互的图形界面,目前我总结了三种qt调用python的方法。

  • 在qt的pro文件中引用python的lib和头文件,使用Py_Initialize()等方法对python方法进行初始化、调用及释放资源。
  • pyqt。一种使用python写qt代码的方法。
  • qt5.12开始支持python,新增了pyside2。

这里使用第一种方法。
在qt新建一个工程,右键单击工程-->Add library-->External library添加python库如下图所示:

python+qt实现CS端软件自动更新的功能_第1张图片

python库一般在/usr/lib。我个人的是:

lib在/usr/lib/python3.6/config-3.6m-x86_64-linux-gnu/libpython3.6m.a

include在/usr/include/python3.6m

添加到pro文件后就可以调用python了。qt代码如下:

#include "mainwindow.h"
#include "ui_mainwindow.h"
#include 
MainWindow::MainWindow(QWidget *parent) :
    QMainWindow(parent),
    ui(new Ui::MainWindow)
{
    ui->setupUi(this);

}

MainWindow::~MainWindow()
{
    delete ui;
}

void MainWindow::on_pushButton_clicked()
{
    Py_Initialize();
    if(!Py_IsInitialized())
    {
        printf("pyinit error!\n");
    }
    PyRun_SimpleString("import sys");
    PyRun_SimpleString("sys.path.append('./')");//设置python文件的路径,我把它拷贝到了qt可执行文件的同级目录,所以是./
    PyObject* pModule=PyImport_ImportModule("pydownhttp");
    if(!pModule){
        printf("Can not open python file!");
    }
    PyObject* pFundown=PyObject_GetAttrString(pModule,"downfile");
    if(!pFundown){
        printf("Get function failed");
    }
    PyObject_CallFunction(pFundown,"ss","http://你的下载地址",
                          "/home/你要保存为的文件");//ss是两个字符串形参的意思,int类型的话就是i。
    Py_Finalize();

}

最终结果:点击button后成功调用python函数下载完成

python+qt实现CS端软件自动更新的功能_第2张图片

三、后记

当然,这个需求用qt的get直接进行下载是最方便的,原理基本一样。这里只是想看一下qt调用python来完成是否可行。关于上传文件到网站这个步骤,博主在之前的工作中就已经做了,因此不再赘述,之后有时间再贴这部分代码。

参考博客:https://blog.csdn.net/qq_35203425/article/details/80987451

你可能感兴趣的:(python+qt实现CS端软件自动更新的功能)