广告
返回顶部
首页 > 资讯 > 后端开发 > Python >Python集成C#实现界面操作下载文件功能的示例分析
  • 481
分享到

Python集成C#实现界面操作下载文件功能的示例分析

2023-06-29 14:06:55 481人浏览 八月长安

Python 官方文档:入门教程 => 点击学习

摘要

这篇文章给大家分享的是有关python集成C#实现界面操作下载文件功能的示例分析的内容。小编觉得挺实用的,因此分享给大家做个参考,一起跟随小编过来看看吧。一、这个功能是怎么样的我很熟悉用 C# & winform 的方式开发界面,现

这篇文章给大家分享的是有关python集成C#实现界面操作下载文件功能的示例分析的内容。小编觉得挺实用的,因此分享给大家做个参考,一起跟随小编过来看看吧。

一、这个功能是怎么样的

我很熟悉用 C# & winform 的方式开发界面,现在刚好学习Python网络编程的基础库 Socket,于是我就想到写一个程序,思路如下:

  • 程序运行时会打开一个 WinFORM 窗体,窗体上有:

    • 输入文件下载地址的地址栏

    • 选择文件保存位置的文件开窗按钮

    • 当前下载状态的状态区域

    • 下载按钮

  • 输入下载地址,选择一个文件保存位置

  • 点击下载按钮下载文件,状态区域显示文件下载状态,最好能显示下载进度

  • 界面放到 WinForm,下载功能放到 Python

二、WinForm 端功能实现

WinForm 分为几部分功能

  • 界面设计

  • 提供下载地址的公共属性

  • 提供文件存储地址公共属性

  • 提供用于委托下载事件的委托定义

  • 提供记录状态信息的公共方法

  • 提供更新进度信息的公共方法

1. 界面设计

首先我们使用 VS 创建一个类库项目

Python集成C#实现界面操作下载文件功能的示例分析

至于为什么没有使用 .net 5 或者 .net core,是因为:Python 调用 C# 动态链接库

Python集成C#实现界面操作下载文件功能的示例分析

创建项目后新建窗体

Python集成C#实现界面操作下载文件功能的示例分析

本例中设计界面设计如下:

Python集成C#实现界面操作下载文件功能的示例分析

2. 方法定义

/// <summary>/// 当前地址/// </summary>public string ThisUrl{    get    {        return textUrl.Text;    }}/// <summary>/// 当前保存路径/// </summary>public string ThisSavePath{    get    {        return textSavePath.Text;    }}
/// <summary>/// 下载事件委托/// </summary>public event EventHandler DownloadEvent;/// <summary>/// 下载按钮事件/// </summary>/// <param name="sender"></param>/// <param name="e"></param>private void buttonDownload_Click(object sender, EventArgs e){    if (string.IsNullOrEmpty(this.textUrl.Text))    {        MessageBox.Show("请先输入要下载的文件地址!");        this.textUrl.Focus();        return;    }    if (string.IsNullOrEmpty(this.textSavePath.Text))    {        MessageBox.Show("请先选择文件要保存的地址!");        this.textSavePath.Focus();        return;    }        // 调用委托事件    if(this.DownloadEvent != null)    {        this.DownloadEvent.Invoke(this, e);    }}

打开选择保存文件路径时候由于会报错

在可以调用OLE之前,必须将当前线程设置为单线程单元(STA)模式,请确保您的Main函数带有STAThreadAttribute标记

很无奈,因为我们的调用方并不是 C# 的 Main 函数,而我目前并不知道 Python 调用 C# 如何实现的,所以只能另外想方法,就是把选择保存文件路径的开窗单独启一个线程开发,在子线程上再标记 STA

/// 选择按钮事件/// </summary>/// <param name="sender"></param>/// <param name="e"></param>private void buttonSelect_Click(object sender, EventArgs e){    if (string.IsNullOrEmpty(this.textUrl.Text))    {        MessageBox.Show("请先输入要下载的文件地址!");        this.textUrl.Focus();        return;    }    var index = this.textUrl.Text.LastIndexOf("/");    var fileName = this.textUrl.Text.Substring(index + 1);    Thread importThread = new Thread(() => {        var text = OpenDialog(fileName);        MessageEvent(text);    });    importThread.SetApartmentState(ApartmentState.STA); //重点    importThread.Start();}/// <summary>/// 打开对话框/// </summary>private string OpenDialog(string fileName){    var saveFileDialog = new SaveFileDialog();    saveFileDialog.Filter = "所有文件 (*.*)|*.*";    saveFileDialog.FilterIndex = 0;    if (!string.IsNullOrEmpty(fileName))    {        saveFileDialog.FileName = Path.Combine(saveFileDialog.FileName, fileName);    }    DialogResult dialogResult = saveFileDialog.ShowDialog();    if (dialogResult == DialogResult.OK)    {        return saveFileDialog.FileName;    }    return String.Empty;}

三、Python 端功能实现

Python 中分几部分功能

  • 程序调用 .NET 类库打开窗体

  • 程序中存在下载指定 URL 文件存储到指定路径的函数定义

  • 程序结束的函数定义

  • 把当前程序封装成可运行程序(如:windows 中为封装成 exe)

import socketimport timeimport remainapp = None# 调用动态链接库的更新状态信息def LogInfo(text):    # print(text)    mainapp.LogInfo(text)    # 调用动态链接库的更新下载进度def downloadInfo(c, all):    mainapp.SetProcess(c, all)    if c == all:        # LogInfo("下载进度 {:.2f}".format(c / all * 100))        LogInfo("下载完成。")    # else:        # LogInfo("下载进度 {:.2f}%".format(c / all * 100))# 监听下载委托事件def Download(source, args):    thisurl = source.ThisUrl.lower()    thispath = source.ThisSavePath    LogInfo("下载地址是: {}".format(thisurl))    LogInfo("保存路径为: {}".format(thispath))        reobj = re.compile(r"""(?xi)\A    [a-z][a-z0-9+\-.]*://                                # Scheme    ([a-z0-9\-._~%!$&'()*+,;=]+@)?                       # User    ([a-z0-9\-._~%]+                                     # Named or IPv4 host    |\[[a-z0-9\-._~%!$&'()*+,;=:]+\])                    # IPv6+ host    """)    match = reobj.search(thisurl)    if match:        HOST = match.group(2)        PORT = 443 if thisurl.startswith('https') else 80        mysock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)        mysock.connect((HOST, PORT))                urlend = 'GET {} Http/1.0\r\n\r\n'.format(thisurl).encode()        # LogInfo("传递参数: {}".format(urlend))        LogInfo("开始下载……")        mysock.sendall(urlend)        count = 0                picture = b""        hearlength = 0        filelength = 0        hearc = b""        while True:            data = mysock.recv(5120)            if (len(data) < 1): break            time.sleep(0.1)            count = count + len(data)            picture = picture + data                        # print(len(data), count)            if hearlength == 0:                hearlength = picture.find(b"\r\n\r\n")                if hearlength > 0:                    hearc = picture[:hearlength].decode()                    # print(hearc)                    sear = re.search('Content-Length: ([0-9]+)', hearc)                    if sear:                        filelength = int(sear.groups()[0])                        downloadInfo(count - 4 - hearlength, filelength)            else:                downloadInfo(count - 4 - hearlength, filelength)        mysock.close()        # Skip past the header and save the picture data        picture = picture[hearlength+4:]        fhand = open(thispath, "wb")        fhand.write(picture)        fhand.close()        # Code: http://www.py4e.com/code3/urljpeg.py        # Or select Download from this trinket's left-hand menu    else:        LogInfo('下载失败,地址格式存在问题!')# 使用 pythonnet 的方式引入动态链接库import clr# 此处保证动态链接库文件放在当前文件夹中,如果不在应该使用这种方式# clr.AddReference('D:\\Path\\dotnetWithPython')# clr.AddReference('D:\\Path\\DotNetWithPython.dll')clr.AddReference('DotNetWithPython')from DotNetWithPython import *mainapp = MainForm()mainapp.DownloadEvent += Downloadmainapp.ShowDialog()

四、运行效果

Python集成C#实现界面操作下载文件功能的示例分析

Python集成C#实现界面操作下载文件功能的示例分析

五、存在问题

功能实现了,但是存在一个无法解决的问题,就是当文件开始下载后 WinForm 的界面会卡住,疑似是没有用现线程打开主窗体的原因,但是不能解释为什么下载开始的时候没有卡顿,有哪位大白指导一下呢?不胜感激!

Python集成C#实现界面操作下载文件功能的示例分析

感谢各位的阅读!关于“Python集成C#实现界面操作下载文件功能的示例分析”这篇文章就分享到这里了,希望以上内容可以对大家有一定的帮助,让大家可以学到更多知识,如果觉得文章不错,可以把它分享出去让更多的人看到吧!

--结束END--

本文标题: Python集成C#实现界面操作下载文件功能的示例分析

本文链接: https://www.lsjlt.com/news/325398.html(转载时请注明来源链接)

有问题或投稿请发送至: 邮箱/279061341@qq.com    QQ/279061341

本篇文章演示代码以及资料文档资料下载

下载Word文档到电脑,方便收藏和打印~

下载Word文档
猜你喜欢
  • Python集成C#实现界面操作下载文件功能的示例分析
    这篇文章给大家分享的是有关Python集成C#实现界面操作下载文件功能的示例分析的内容。小编觉得挺实用的,因此分享给大家做个参考,一起跟随小编过来看看吧。一、这个功能是怎么样的我很熟悉用 C# & WinForm 的方式开发界面,现...
    99+
    2023-06-29
  • Python集成C#实现界面操作下载文件功能的全过程
    目录〇、写在前面一、这个功能是怎么样的二、WinForm 端功能实现1. 界面设计2. 方法定义三、Python 端功能实现四、运行效果五、存在问题总结〇、写在前面 你想的没错,Py...
    99+
    2022-11-13
  • AngularJS基于http请求实现下载php生成的excel文件功能示例
    这篇文章将为大家详细讲解有关AngularJS基于http请求实现下载php生成的excel文件功能示例,小编觉得挺实用的,因此分享给大家做个参考,希望大家阅读完这篇文章后可以有所收获。使用PHPExcel...
    99+
    2022-10-19
软考高级职称资格查询
编程网,编程工程师的家园,是目前国内优秀的开源技术社区之一,形成了由开源软件库、代码分享、资讯、协作翻译、讨论区和博客等几大频道内容,为IT开发者提供了一个发现、使用、并交流开源技术的平台。
  • 官方手机版

  • 微信公众号

  • 商务合作