开发一个ftp上传客户端

文章目录

  • 需求
  • 分析
    • Tkinter
    • 基本用法
    • 多窗口切换
    • FTP上传
  • 程序打包
  • 源码

需求

项目中有个小功能模块 ,需要win下实现ftp上传功能,编写一个DEMO测试
要求

  • 界面简单
  • 选择本地文件 上传ftp服务器
  • 显示进度条
  • 显示状态
  • 上传完成后显示URL分享地址

分析

Tkinter

Tkinter 是 Python 的标准 GUI(图形用户界面)库,用于创建桌面应用程序。它是 Python 的官方 GUI 库,内置于Python 发行版中,因此无需额外安装即可使用。Tkinter 提供了一组用于创建窗口、对话框、按钮、文本框等 GUI
元素的类和方法。Tkinter 的外观和功能相对基础,复杂功能不使用

  • Tkinter 窗口(Tk):
    创建一个 Tkinter 应用程序时,首先需要创建一个顶层窗口。这通常是通过实例化
  • tkinter.Tk 类来实现的。
    Tkinter 小部件(Widgets):
    小部件是用户界面中用于交互的元素,如按钮、文本框、标签等。Tkinter 提供了多种小部件类,如 Button、Entry、Label 等。
  • 事件处理:
    Tkinter 通过事件处理机制来响应用户操作,如点击按钮、输入文本等。你可以通过绑定事件处理函数到小部件上,来处理这些事件。

基本用法

import tkinter as tk  # 创建顶层窗口  
root = tk.Tk()  
root.title("Tkinter 示例")  
root.geometry("300x200")  # 设置窗口大小  # 创建一个标签  
label = tk.Label(root, text="Hello, Tkinter!")  
label.pack(pady=20)  # 使用 pack 布局管理器,并设置上下填充  # 定义一个按钮点击事件处理函数  
def on_button_click():  label.config(text="按钮已点击!")  # 创建一个按钮,并绑定事件处理函数  
button = tk.Button(root, text="点击我", command=on_button_click)  
button.pack(pady=10)  # 进入主事件循环  
root.mainloop()

在这里插入图片描述

多窗口切换

实现类似Tabs 组件以及选项卡功能

import tkinter as tk  
from tkinter import ttk  class Tabs(tk.Frame):  def __init__(self, master=None, **kw):  super().__init__(master, **kw)  self.master = master  self.tabs = {}  # 用于存储选项卡和对应框架的字典  self.current_tab = None  # 当前显示的选项卡  # 创建一个框架来放置选项卡头部  self.header_frame = tk.Frame(self)  self.header_frame.pack(fill=tk.X)  # 创建一个框架来放置选项卡内容  self.content_frame = tk.Frame(self)  self.content_frame.pack(fill=tk.BOTH, expand=True)  def add_tab(self, tab_name, content):  # 创建选项卡头部按钮  tab_button = ttk.Button(self.header_frame, text=tab_name, command=lambda: self.switch_tab(tab_name))  tab_button.pack(side=tk.LEFT, fill=tk.X, expand=True)  # 创建内容框架并添加到字典中  content_frame = tk.Frame(self.content_frame)  content_frame.grid(row=0, column=0, sticky="nsew")  self.tabs[tab_name] = content_frame  # 将内容添加到内容框架中(这里假设content是一个widget或widget的创建函数)  if callable(content):  content(content_frame)  # 如果这是第一个选项卡,则默认显示它  if self.current_tab is None:  self.current_tab = tab_name  content_frame.grid_propagate(False)  # 禁止内容框架自动调整大小  content_frame.grid_rowconfigure(0, weight=1)  content_frame.grid_columnconfigure(0, weight=1)  self.content_frame.grid_rowconfigure(0, weight=1)  self.content_frame.grid_columnconfigure(0, weight=1)  content_frame.tkraise()  # 将内容框架置于顶层  def switch_tab(self, tab_name):  # 隐藏当前选项卡的内容框架  if self.current_tab:  self.tabs[self.current_tab].grid_remove()  # 显示新的选项卡内容框架  self.current_tab = tab_name  self.tabs[tab_name].grid(row=0, column=0, sticky="nsew")  self.tabs[tab_name].tkraise()  # 确保新的内容框架在顶层  self.tabs[tab_name].grid_propagate(False)  # 禁止内容框架自动调整大小(如果需要)  # 示例使用  
def create_tab_content_a(frame):  label = tk.Label(frame, text="This is content for Tab A")  label.pack(pady=20, padx=20)  def create_tab_content_b(frame):  entry = tk.Entry(frame)  entry.pack(pady=20, padx=20)  root = tk.Tk()  
root.title("模拟实现TAB切换")  
root.geometry("600x400")  # 设置窗口大小 tabs = Tabs(root)  
tabs.pack(fill=tk.BOTH, expand=True)  # 添加选项卡  
tabs.add_tab("文件上传", create_tab_content_a)  
tabs.add_tab("文件列表", create_tab_content_b)  root.mainloop()

在这里插入图片描述

FTP上传

在Python中实现FTP文件上传功能可以使用ftplib模块,这是一个内置的库,提供了对FTP协议的支持。首先,需要确保有权限访问目标FTP服务器。此外,需要准备好要上传的文件路径和FTP服务器的相关信息(如主机名、用户名、密码等)
可以先使用命令行工具进行测试确保没有问题

下面是 ftplib 中一些常用的函数和方法

  • FTP 类:
    构造函数: FTP(host=‘’, user=‘’, passwd=‘’, acct=‘’, timeout=None, source_address=None)
    创建一个 FTP 对象,并连接到指定的主机。
  • 登录相关的方法:
    login(user=‘’, passwd=‘’, acct=‘’): 使用提供的用户名、密码登录到 FTP 服务器。
    quit(): 发送 QUIT 命令给服务器并关闭连接。
  • 目录操作:
    cwd(pathname): 更改当前工作目录。
    pwd(): 获取当前工作目录。
    mkd(dirname): 创建新目录。
    rmd(dirname): 删除目录。
    nlst([arg]): 列出目录内容,如果提供了参数,则列出该目录下的内容;如果没有提供参数,则列出当前目录的内容。
    dir([arg]): 打印目录列表详情。
  • 文件传输:
retrbinary(cmd, callback, blocksize=8192, rest=None): 以二进制模式接收数据。
retrlines(cmd, callback=None): 以行文本模式接收数据。
storbinary(cmd, fp, blocksize=8192, callback=None, rest=None): 以二进制模式发送数据。
storlines(cmd, fp, callback=None): 以行文本模式发送数据。
  • 其他常用方法:
set_pasv(val=True): 设置是否使用被动模式(默认为 True)。
getwelcome(): 返回服务器欢迎信息。
rename(fromname, toname): 重命名远程文件或目录。
delete(filename): 删除远程文件。
size(filename): 返回远程文件大小。
voidcmd(cmd): 发送任意命令但不关心响应。

示例代码

from ftplib import FTP# 连接到FTP服务器
ftp = FTP('your.ftp.server.com')
ftp.login('username', 'password')# 切换到某个目录
ftp.cwd('/path/to/directory')# 列出当前目录下的所有文件
files = ftp.nlst()
print("Files in directory:", files)# 上传文件
with open('localfile.txt', 'rb') as file:ftp.storbinary('STOR remote_file.txt', file)
print("File has been uploaded.")# 下载文件
with open('downloaded_file.txt', 'wb') as file:ftp.retrbinary('RETR remote_file.txt', file.write)
print("File has been downloaded.")# 关闭连接
ftp.quit()

程序打包

需求 Windows 环境下将python程序打包为exe

在 Windows 下将 Python 程序打包成可执行文件(.exe),最常用的方法是使用 PyInstaller
安装
pip install pyinstaller

常见使用方法

pyinstaller --onefile my_script.py

–onefile 参数告诉 PyInstaller 将所有依赖和代码打包进一个单独的 .exe 文件中。
如果不加此参数,PyInstaller 会生成一个包含多个文件的目录。
默认情况下,生成的 .exe 文件位于 dist 目录下。你可以找到 dist/my_script.exe 文件。

–windowed:如果你的应用是一个 GUI 应用(如使用 Tkinter、PyQt 或 wxPython 编写的),并且你不希望显示控制台窗口,可以添加这个选项

–icon=your_icon.ico:为你的 .exe 文件指定一个图标

–hidden-import package_name:如果你的脚本动态导入了一些模块,而这些模块没有被自动检测到,你可以手动指定它们。

源码

import tkinter as tk  
from tkinter import ttk,filedialog
from ftplib import FTP  
from threading import Thread  
import os  
import time
import datetimeclass FTPUploader:  def __init__(self, file_path, ftp_server, ftp_user, ftp_password, remote_path, progress_var,status_label):  self.file_path = file_path  self.ftp_server = ftp_server  self.ftp_user = ftp_user  self.ftp_password = ftp_password  self.remote_path = remote_path  self.progress_var = progress_varself.uploaded_bytes = 0  # Track the uploaded bytesself.status_label = status_labeldef upload(self):  try:  file_size = os.path.getsize(self.file_path)  with open(self.file_path, 'rb') as file:  ftp = FTP(self.ftp_server)  ftp.login(user=self.ftp_user, passwd=self.ftp_password)  remote_dir, remote_filename = os.path.split(self.remote_path)  if remote_dir:  ftp.cwd(remote_dir)  # Define the callback function for progress updates  def update_progress(data): self.uploaded_bytes += len(data)  # Calculate the progress percentage  progress = self.uploaded_bytes / file_size * 100  # Update the progress variable (which is linked to the progressbar)  # Note: This may need to be done in a thread-safe way if the GUI is not thread-safe  self.progress_var.set(progress)  # Start the upload with the callback for progress updates  print(f"Uploading {self.file_path} to {self.remote_path}...")  ftp.storbinary(f'STOR {remote_filename}', file, callback=update_progress)  ftp.quit()print(f"File {self.file_path} uploaded successfully to {self.remote_path}")self.status_label.config(text=f"上传{self.file_path}完成,\n播放地址为 http://10.31.32.40:8087/live/record/{remote_filename}")#self.status_label.config(text=f"上传{self.file_path}完成")except Exception as e:  print(f"Failed to upload file: {e}")class UploadApp:  def __init__(self, root):self.timestamp = datetime.datetime.now().strftime("%Y%m%d%H%M%S")self.root = root# 创建选择文件按钮self.choose_button = tk.Button(root, text="选择文件", command=choose_file)self.choose_button.pack(pady=5)# 创建进度条self.progress_var = tk.DoubleVar()  self.progress_bar = ttk.Progressbar(root, orient="horizontal", maximum=100, mode="determinate", variable=self.progress_var)self.progress_bar.pack(fill=tk.X, padx=20, pady=10)#self.progress_bar.pack(pady=20)# 创建开始上传按钮self.start_button = tk.Button(root, text="开始上传", command=self.start_upload)  self.start_button.pack(pady=20)# 创建状态标签self.status_label = tk.Label(root, text="", fg="blue")  # 设置文本颜色为蓝色以便更明显self.status_label.pack(pady=10)# FTP credentials and file paths (these should be set by the user or securely stored)  #self.local_file_path = 'ftpclient.py'        self.ftp_server = '127.0.0.1'                self.ftp_user = 'ftpuser'                self.ftp_password = '123456'        def start_upload(self):if 'selected_file' not in globals() or not selected_file:self.status_label.config(text="请先选择一个文件!")returnself.status_label.config(text="上传中...")self.progress_var.set(0)self.local_file_path = selected_filelocal_dir, local_filename = os.path.split(self.local_file_path)print(selected_file,self.local_file_path,local_dir,local_filename)self.remote_file_path = f'cctvlive/{local_filename}'#self.remote_file_path = f"cctvlive/{timestamp}.mp4"print("start_upload  ",self.remote_file_path)# Create an instance of the FTPUploader and run it in a separate thread  self.uploader = FTPUploader(self.local_file_path, self.ftp_server, self.ftp_user, self.ftp_password, self.remote_file_path, self.progress_var,self.status_label)  upload_thread = Thread(target=self.uploader.upload)  upload_thread.start()def choose_file():# 打开文件选择对话框filename = filedialog.askopenfilename()if filename:file_label.config(text=f"选中的文件: {filename}")global selected_fileselected_file = filename#progress_var.set(0)selected_file=""if __name__ == "__main__":  root = tk.Tk()root.title("直播录制文件上传")# 设置窗口大小root.geometry('400x250')# 创建并放置文件路径标签file_label = tk.Label(root, text="请选择要上传的文件...")file_label.pack(pady=10)app = UploadApp(root)  root.mainloop()

在这里插入图片描述
在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.xdnf.cn/news/1558504.html

如若内容造成侵权/违法违规/事实不符,请联系一条长河网进行投诉反馈,一经查实,立即删除!

相关文章

【AI绘画SD教程】Lineart线稿上色和IP-Adapter 人像写真插件实操教学,轻松助你生成多种风格的AI人像大片!SD零基础入门到精通教程

大家好,我是画画的小强 今天给大家分享一下如何用AI绘画工具StableDiffusion当中的 LineArt线稿处理 和 IP-Adapter 实操教学。 本期教程开始之前,请先确保你的电脑已经安装好StableDiffusion这款AI绘图工具,如你还没有安装使用&#xff0c…

电桥的作用是什么?

一、电桥的基本概念和原理 电桥是一种测量电阻、电容、电感等电学量的仪器,其原理基于电路中的克希荷夫定律以及欧姆定律。电桥由四个电阻分支组成,在精确测量电阻时,需要把待测电阻与一个已知电阻进行比较,通过调节电桥中的一个…

将流畅度贯彻到底的ColorOS,究竟有何“流畅法宝”?

在智能手机这个无比激烈的竞技场中,系统的流畅度和稳定性往往是衡量用户体验的金标准。 ColorOS作为OPPO手机的操作系统,自2013年诞生以来,便以其卓越的系统流畅度赢得了众多用户的青睐。同时其在2020年创办至今的鲁大师牛角尖盛典中&#x…

学习threejs,光晕效果

👨‍⚕️ 主页: gis分享者 👨‍⚕️ 感谢各位大佬 点赞👍 收藏⭐ 留言📝 加关注✅! 👨‍⚕️ 收录于专栏:threejs gis工程师 文章目录 一、🍀前言二、🍀光晕效果实现1. ☘…

蓝牙模块(BT04/HC05)

目录 一、介绍 二、模块原理 1.原理图与外形尺寸 2.引脚描述 3.蓝牙模块基础AT指令介绍 三、程序设计 usart3.h文件 usart3.c文件 四、实验效果 五、资料获取 项目分享 一、介绍 BT04A是一款蓝牙低功耗(Bluetooth Low Energy, BLE)模块&…

(RAG)技术结合了大模型(LLM)与内部数据,从而实现更智能且相关性更高的 AI 应用

利用先进的生成式 AI 技术(如 RAG),释放数据的潜力,推动创新并获取战略优势 主要功能 使用向量数据库优化数据检索和生成 通过 AI 代理提升决策效率并自动化工作流程 克服实施真实 RAG 系统中的常见挑战 购买印刷版或 Kindle …

股指期货和股指期权有什么区别?

在金融衍生品的世界里,股权类衍生品无疑是其中的佼佼者,而股指期货和股指期权更是其中的佼佼者。尽管它们之间有着千丝万缕的联系,但它们之间的区别同样不容忽视。本文衍生股指君将详细解析股指期货和股指期权的核心区别。 一、交易的东西不…

数据库软题7-数据库设计

一、概念结构设计 题1-ER图的属性分类 题2-局部ER图的冲突分类 1.命名冲突 命名冲突有同名异义,异名同义2.结构冲突 结构冲突分为:统一实体不同属性,同一对象在不同关系里可能为属性或者实体 教师其实就是职工,他们有不同的属性…

5.将扩散模型应用于具有特殊结构的数据

虽然扩散模型在图像和音频等数据应用领域中取得了巨大的成功,但他们不一定能无缝地转移到其他模态上。在许多重要的领域,数据有特殊的结构。为了让扩散模型有效运作,必须考虑并处理这些特殊结构。比如,经典扩散模型所依赖的分数的…

「JVS更新日志」低代码、智能BI、逻辑引擎10.9功能更新说明

项目介绍 JVS是企业级数字化服务构建的基础脚手架,主要解决企业信息化项目交付难、实施效率低、开发成本高的问题,采用微服务配置化的方式,提供了 低代码数据分析物联网的核心能力产品,并构建了协同办公、企业常用的管理工具等&am…

SDUT数据结构与算法第二次机测

目录 7-1 括号匹配 7-2 后缀式求值 7-3 表达式转换 7-4 【模板】KMP字符串匹配 比较详细注释和图解请看KMP——字符串匹配-CSDN博客,(点击链接可跳转)一看就会 7-5 约瑟夫环(押题,重要) 7-6 单调栈&a…

迪士尼数据泄露事件:全面审视数据安全策略与未来防护方向

迪士尼数据泄露事件概述 一、 事件背景以及影响 在全球数字化转型加速的浪潮中,数据安全已成为企业运营不可忽视的基石。 华特迪士尼公司,作为全球知名的娱乐传媒巨头,其数据泄露事件无疑为业界敲响了警钟。此次事件不仅揭示了数据保护的严…

Pymysql cur.fetchall() 返回 None

大家在pymysql 的 cur.fetchall() 函数通常用于获取执行 SQL 查询后的所有结果。该函数返回一个包含查询结果的元组列表。如果 cur.fetchall() 返回 None,可能是由于以下多种问题导致的。 1、问题背景 在使用 Pymysql 库连接到 MySQL 数据库时,遇到这样…

YOLOv5改进——普通卷积和C3模块更换为GhostConvV2卷积和C3GhostV2模块

目录 一、GhostNetV2核心代码 二、修改common.py 三、修改yolo.py 三、建立yaml文件 四、训练 一、GhostNetV2核心代码 在models文件夹下新建modules文件夹,在modules文件夹下新建一个py文件。这里为GhostV2.py。复制以下代码到文件里面。 # TODO: ghostnetv…

好用的免费录屏软件推荐,让软件操作教程制作不再困难

录屏软件就像是我们做教程或者玩游戏时的“小助手”,它能帮我们把屏幕上的东西都记录下来,让视频看起来更高大上。今天我就给你推荐三款免费的好货,用它们做教程,保证让你轻松又开心。 1. 福昕录屏大师 虫洞 https://www.foxits…

【读书笔记·VLSI电路设计方法解密】问题4:今天的设计环境中使用的主要工艺技术是什么

主流的工艺技术是互补金属氧化物半导体(CMOS)技术。其他技术还包括双极性、双极CMOS(biCMOS)、绝缘体上硅(SOI)和砷化镓(GaAs)。 在CMOS技术中,"互补对称"指的…

SD入门教程一:Stable Diffusion 基础(技术篇)

前言 在开篇的时候就大致讲了SD和VAE,那么今天我们具象化地再来讲讲Stable Diffusion(稳定扩散)。 严格说来它是一个由几个组件(模型)构成的系统,而非单独的一个模型。我以最常见的文生图为例,…

大型保险公司进行营销活动时,如何与外部客户实现文件安全外发?

大型保险公司为了吸引新客户、维护老客户、提升品牌形象以及推广特定的保险产品,会定期向外部客户或潜在客户发送营销文件。在客户签单后,保险公司会将客户相关的签单个人文件发送给客户。因此,大型保险公司内部存在较为频繁且重要的文件安全…

安装DNS

在 CentOS 7 上安装并配置 BIND 以实现 DNS 的正向和反向解析可以按照以下步骤进行: 安装 BIND 打开终端并运行以下命令来安装 BIND 及其工具: yum install bind bind-utils -y配置 BIND 编辑主配置文件: 使用文本编辑器打开 BIND 的主配…

电商价格监测的创新之路

在当今数字化高速发展的时代,电商如汹涌的浪潮席卷了商业的每一个角落。品牌们在这片广阔的电商海洋中奋力前行,而价格监测则成为了他们手中至关重要的罗盘。 力维网络以其专业的价格监测服务,为品牌在电商之海的航行点亮了一盏明灯。然而&a…