1.先选择本地的一个目录进行文件展示
2.本地搜索是基于第一步选择本地目录的路径进行搜索的
3.ftp搜索是基于当前ftp显示这个页面进行搜索的
4.左边本地展示框和右边ftp展示框支持拖拽上传,前提是先要选择一个目录。
在这个项目中有两个最大的bug还未解决
1.上传到ftp中文目录中会出现乱码
2.上传和下载显示的进度条是一个假的进度条
欢迎各位大佬对这两个bug进行修改
import tkinter as tk
from tkinter import ttk
from ftp_client_alter_bug.bottom_menu.bottom_menu_bar_center import BottomMenuBarCenter
from ftp_client_alter_bug.seek.win_search import WinSearch
from ftp_client_alter_bug.top_menu.top_menu_bar import TopMenuBar
from ftp_client_alter_bug.bottom_menu.bottom_menu_bar_left import BottomMenuBarleft
from ftp_client_alter_bug.bottom_menu.bottom_menu_bar_right import BottomMenuBarRight
from ftp_client_alter_bug.tree.win_tree import WinTree
from ftp_client_alter_bug.tree.ftp_tree import FtpTree
from ftp_client_alter_bug.win_ftp_drag.ftpdrag import FtpDrag
from ftp_client_alter_bug.win_ftp_drag.windrag import WinDrag
win = tk.Tk()
win.title("FTP客户端")
win.geometry("1200x700")
win.resizable(0, 0)
xuanzhe_win_path = []
win_path = []
ftp_path = []
win_search_name = []
win_search_path = []
ftp_search_path = []
ftp_list = []
ftp_tree_list = []
win_xuanze_tree = []
win_search_tree = []
path = "初始化占位"
top_frame = tk.Frame(win, width="1200", height="60")
top_frame.place(x=0, y=5)
top_menu = TopMenuBar(top_frame, path, win, win_search_path, ftp_list, xuanzhe_win_path)
top_menu.logo()
top_menu.open_wenjian()
# top_menu.search_box()
top_menu.name_ip("", "")
top_menu.exit_login(ftp_tree_list, ftp_path, ftp_list)
top_menu.login_in(ftp_path, ftp_list, ftp_tree_list)
top_menu.lishi_login_in(ftp_path, ftp_list, ftp_tree_list)
left_frame = tk.Frame(win, width="350", height="540")
left_frame.place(x=10, y=90)
tree = ttk.Treeview(left_frame, show="tree", height=26)
tree.column("#0", width=350)
st = ttk.Style()
st.configure("Treeview", font=("宋体", 13))
winftpdrag = WinDrag(left_frame, win_path, xuanzhe_win_path, tree)
winftpdrag.execute()
win_xuanze_tree.clear()
win_xuanze_tree.append(tree)
wintree = WinTree(path, win_path, tree)
top_menu.local_mulu(win_path, tree)
# 创建两个一模一样的frame实现一个注销一个加载
win_center_frame = tk.Frame(win, width="420",bg="green", height="540")
win_center_frame.place(x=350, y=90)
search_path = r"D:\\python_daima"
search_name = "9999"
win_tree = ttk.Treeview(win_center_frame, show="tree", height=26)
win_tree.column("#0", width=440)
st = ttk.Style()
st.configure("Treeview", font=("宋体", 12))
win_search_tree.clear()
win_search_tree.append(win_tree)
winsearch = WinSearch(path, search_name, win_search_path, win_tree)
top_menu.search_box(win_search_name, win_search_tree, ftp_search_path, ftp_list)
right_frame = tk.Frame(win, width="420", height="540")
right_frame.place(x=790, y=90)
tree_ftp = ttk.Treeview(right_frame, show="tree", height=26, columns=("shijian", "wenjiantype"))
tree_ftp.column("#0", width=250)
tree_ftp.column("shijian", width=80)
tree_ftp.column("wenjiantype", width=60)
ftp_tree_list.append(tree_ftp)
st = ttk.Style()
st.configure("Treeview", font=("宋体", 13))
bommot_frame_left = tk.Frame(win, width="350", height="60")
bommot_frame_left.place(x=0, y=635)
bommot_menu_left = BottomMenuBarleft(bommot_frame_left)
bommot_menu_left.win_chuangjian_mulu(win_path, xuanzhe_win_path, tree)
bommot_menu_left.win_chuangjian_wenjian(win_path, xuanzhe_win_path, tree)
bommot_menu_left.win_delete_mulu(win_path, xuanzhe_win_path, tree)
bommot_menu_left.win_delete_wenjian(win_path, xuanzhe_win_path, tree)
# bommot_menu_left.shangchaung(win, ftp_path, ftp_list, ftp_frame, ftp_tree, win_path, bommot_frame_center)
bommot_menu_left.open_wenjian(win_path)
bommot_menu_left.gexian()
bommot_frame_center = tk.Frame(win, width="500", height="60")
bommot_frame_center.place(x=350, y=635)
bottom_menu_center = BottomMenuBarCenter(bommot_frame_center)
bottom_menu_center.delete_mulu(win_search_path, xuanzhe_win_path, win_search_name, win_tree, win_path, tree)
bottom_menu_center.open_weizhi(win_search_path)
bottom_menu_center.delete_wenjian(ftp_list, tree_ftp, ftp_path, win_search_name, win_search_tree, ftp_search_path)
bottom_menu_center.xiazai_wenjian(ftp_list, win_path, xuanzhe_win_path, bommot_frame_center, tree, ftp_search_path)
bottom_menu_center.gexian()
ftptree = FtpTree(ftp_path, ftp_list, tree_ftp)
ftpdrag = FtpDrag(right_frame, ftp_path, ftp_list, win_path, bommot_frame_center, tree_ftp)
ftpdrag.execute()
bommot_menu_left.shangchaung(ftp_path, ftp_list, win_path, bommot_frame_center, tree_ftp)
bommot_frame_right = tk.Frame(win, width="350", height="60")
bommot_frame_right.place(x=850, y=635)
bommot_menu_right = BottomMenuBarRight(bommot_frame_right)
bommot_menu_right.geban()
bommot_menu_right.ftp_chaungjian_mulu(ftp_path, ftp_list, tree_ftp)
bommot_menu_right.ftp_jinru_xj(ftp_path, ftp_list, tree_ftp)
bommot_menu_right.ftp_delete_mulu(ftp_path, ftp_list, tree_ftp)
bommot_menu_right.ftp_delete_wenjian(ftp_path, ftp_list, tree_ftp)
bommot_menu_right.xiazai(ftp_list, ftp_path, win_path, xuanzhe_win_path, bommot_frame_center, tree)
bommot_menu_right.ftp_fh_sj(ftp_path, ftp_list, tree_ftp)
tk.mainloop()
import tkinter as tk
import os
from tkinter.messagebox import showinfo
from ftp_client_alter_bug.tree.ftp_tree import FtpTree
from ftp_client_alter_bug.tree.win_tree import WinTree
from ftp_client_alter_bug.seek.ftp_search import FtpSearch
from ftp_client_alter_bug.seek.win_search import WinSearch
class BottomMenuBarCenter:
def __init__(self, bommot_frame_center):
self.bommot_frame_center = bommot_frame_center
# win删除文件
def delete_mulu(self, win_search_path, xuanzhe_win_path, win_search_name, win_tree, win_path, tree):
def delete_mulu_button():
try:
# 也可以递归删除文件
def delAll(path):
if os.path.isdir(path):
files = os.listdir(path)
# 遍历并删除文件
for file in files:
p = os.path.join(path, file)
if os.path.isdir(p):
# 递归
delAll(p)
else:
os.remove(p)
# 删除文件夹
os.rmdir(path)
else:
os.remove(path)
delAll(win_search_path[0])
table = win_tree
items = table.get_children()
[table.delete(item) for item in items]
win_name = win_search_name[0]
winsearch = WinSearch(xuanzhe_win_path[0], win_name, win_search_path, win_tree)
winsearch.search()
table = tree
items = table.get_children()
[table.delete(item) for item in items]
wintree = WinTree(xuanzhe_win_path[0], win_path, tree)
wintree.show_wenjian()
except:
showinfo("错误提示", "路径选择异常!")
delete_mulu_but = tk.Button(self.bommot_frame_center, text="删除文件", command=delete_mulu_button, font=("宋体", 13), relief="flat")
delete_mulu_but.place(x=15, y=2)
# 打开window上文件所在的位置
def open_weizhi(self, win_search_path):
def open_weizhi_button():
try:
os.startfile(rf"{win_search_path[0]}")
except:
showinfo("错误提示", "未选择路径!")
open_weizhi_but = tk.Button(self.bommot_frame_center, text="打开文件", command=open_weizhi_button, font=("宋体", 13), relief="flat")
open_weizhi_but.place(x=15, y=35)
# ftp删除文件
def delete_wenjian(self, ftp_list, tree_ftp, ftp_path, win_search_name, win_search_tree, ftp_search_path):
def delete_wenjian_button():
try:
ftp_list[0].delete(ftp_search_path[0])
if str(ftp_list[0].pwd()) != "/":
table = tree_ftp
items = table.get_children()
[table.delete(item) for item in items]
ftptree = FtpTree(ftp_path, ftp_list, tree_ftp)
ftptree.xianshi(ftp_list[0].pwd())
else:
table = tree_ftp
items = table.get_children()
[table.delete(item) for item in items]
ftptree = FtpTree(ftp_path, ftp_list, tree_ftp)
ftptree.xianshi("/")
win_name = win_search_name[0]
table = win_search_tree[0]
items = table.get_children()
[table.delete(item) for item in items]
ftpsearch = FtpSearch(ftp_list[0], win_name, ftp_search_path, table)
ftpsearch.show()
except:
showinfo("错误提示", "路径选择或服务器连接异常!")
delete_wenjian_but = tk.Button(self.bommot_frame_center, text="删除文件", command=delete_wenjian_button, font=("宋体", 13), relief="flat")
delete_wenjian_but.place(x=415, y=2)
# ftp下载文件
def xiazai_wenjian(self, ftp_list, win_path, xuanzhe_win_path, bommot_frame_center, tree, ftp_search_path):
def xiazai_wenjian_button():
try:
print(ftp_list[0], ftp_search_path[0], win_path[0], "三个路径————————")
def downloadfile(ftp, remotepath, localpath):
bufsize = 1024 # 设置缓冲块大小
fp = open(localpath, 'wb') # 以写模式在本地打开文件
ftp.retrbinary('RETR ' + remotepath, fp.write, bufsize) # 接收服务器上文件并写入本地文件
ftp.set_debuglevel(0) # 关闭调试
fp.close() # 关闭文件
downloadfile(ftp_list[0], ftp_search_path[0], win_path[0]+"\\"+ftp_search_path[0].split("/")[-1])
# 更新进度条函数
def change_schedule(now_schedule, all_schedule):
canvas.coords(fill_rec, (5, 5, 6 + (now_schedule / all_schedule) * 100, 25))
bommot_frame_center.update()
x.set(str(round(now_schedule / all_schedule * 100, 2)) + '%')
if round(now_schedule / all_schedule * 100, 2) == 100.00:
x.set("完==成==了")
canvas = tk.Canvas(bommot_frame_center, width=110, height=30, bg="white")
canvas.place(x=150, y=25)
x = tk.StringVar()
# 进度条以及完成程度
out_rec = canvas.create_rectangle(5, 5, 105, 25, outline="blue", width=1)
fill_rec = canvas.create_rectangle(5, 5, 5, 25, outline="", width=0, fill="blue")
tk.Label(bommot_frame_center, textvariable=x, font=("宋体", 13)).place(x=280, y=30)
for i in range(100):
change_schedule(i, 99)
table = tree
items = table.get_children()
[table.delete(item) for item in items]
wintree = WinTree(xuanzhe_win_path[0], win_path, tree)
wintree.show_wenjian()
print(win_path[0]+ftp_search_path[0].split("\\")[-1],"============================")
except:
showinfo("错误提示", "本地路径或服务器连接异常!")
xiazai_wenjian_but = tk.Button(self.bommot_frame_center, text="下载文件", command=xiazai_wenjian_button, font=("宋体", 13), relief="flat")
xiazai_wenjian_but.place(x=415, y=35)
def gexian(self):
tk.Label(self.bommot_frame_center, text="-------------进-------------度--------------条-------------").place(x=105, y=0)
import tkinter as tk
import os
from tkinter.messagebox import showinfo
from ftp_client_alter_bug.tree.ftp_tree import FtpTree
from ftp_client_alter_bug.tree.win_tree import WinTree
class BottomMenuBarleft:
def __init__(self, bommot_frame_left):
self.bommot_frame_left = bommot_frame_left
# 创建本地目录
def win_chuangjian_mulu(self, win_path, xuanzhe_win_path, tree):
def win_mulu_button():
cj_mulu_win = tk.Tk()
cj_mulu_win.geometry("300x170")
tk.Label(cj_mulu_win, text="创建目录", font=("宋体", 17)).place(x=100, y=15)
tk.Label(cj_mulu_win, text="目录名:", font=("宋体", 13)).place(x=30, y=60)
mulu_entry = tk.Entry(cj_mulu_win, width=17, font=("宋体", 13))
mulu_entry.place(x=100, y=60)
def mulu_but():
try:
mulu_name = str(mulu_entry.get())
os.mkdir(win_path[0] + "\\" + mulu_name)
table = tree
items = table.get_children()
[table.delete(item) for item in items]
wintree = WinTree(xuanzhe_win_path[0], win_path, tree)
wintree.show_wenjian()
# cj_mulu_win.destroy()
except:
showinfo("错误提示", "未选择路径!")
finally:
cj_mulu_win.destroy()
mulu_button = tk.Button(cj_mulu_win, text="确==========定", font=("宋体", 13), command=mulu_but)
mulu_button.place(x=80, y=105)
cj_mulu_win.mainloop()
win_mulu_but = tk.Button(self.bommot_frame_left, text="创建目录", font=("宋体", 13), command=win_mulu_button, relief="flat")
win_mulu_but.place(x=10, y=2)
# 创建本地文件
def win_chuangjian_wenjian(self, win_path, xuanzhe_win_path, tree):
def win_wenjian_button():
cj_wenjian_win = tk.Tk()
cj_wenjian_win.geometry("300x170")
tk.Label(cj_wenjian_win, text="创建文件", font=("宋体", 17)).place(x=100, y=15)
tk.Label(cj_wenjian_win, text="文件名:", font=("宋体", 13)).place(x=30, y=60)
wenjian_entry = tk.Entry(cj_wenjian_win, width=17, font=("宋体", 13))
wenjian_entry.place(x=100, y=60)
def wenjian_but():
try:
wenjian_name = str(wenjian_entry.get())
f = open(win_path[0] + "\\" + wenjian_name, "w")
f.close()
table = tree
items = table.get_children()
[table.delete(item) for item in items]
wintree = WinTree(xuanzhe_win_path[0], win_path, tree)
wintree.show_wenjian()
# cj_wenjian_win.destroy()
except:
showinfo("错误提示", "未选择路径!")
finally:
cj_wenjian_win.destroy()
wenjian_button = tk.Button(cj_wenjian_win, text="确==========定", font=("宋体", 13), command=wenjian_but)
wenjian_button.place(x=80, y=105)
win_wenjian_but = tk.Button(self.bommot_frame_left, text="创建文件", font=("宋体", 13), command=win_wenjian_button, relief="flat")
win_wenjian_but.place(x=10, y=35)
# 删除目录
def win_delete_mulu(self, win_path, xuanzhe_win_path, tree):
def win_mulu_delete_button():
try:
path = win_path[0]
# 也可以递归删除文件
def delAll(path):
if os.path.isdir(path):
files = os.listdir(path)
# 遍历并删除文件
for file in files:
p = os.path.join(path, file)
if os.path.isdir(p):
# 递归
delAll(p)
else:
os.remove(p)
# 删除文件夹
os.rmdir(path)
else:
os.remove(path)
delAll(path)
table = tree
items = table.get_children()
[table.delete(item) for item in items]
wintree = WinTree(xuanzhe_win_path[0], win_path, tree)
wintree.show_wenjian()
except:
showinfo("错误提示", "未选择路径!")
win_delete_mu_but = tk.Button(self.bommot_frame_left, text="删除目录", font=("宋体", 13), command=win_mulu_delete_button, relief="flat")
win_delete_mu_but.place(x=115, y=2)
# 删除文件
def win_delete_wenjian(self, win_path, xuanzhe_win_path, tree):
def win_wenjian_delete_button():
try:
path = win_path[0]
# 也可以递归删除文件
def delAll(path):
if os.path.isdir(path):
files = os.listdir(path)
# 遍历并删除文件
for file in files:
p = os.path.join(path, file)
if os.path.isdir(p):
# 递归
delAll(p)
else:
os.remove(p)
# 删除文件夹
os.rmdir(path)
else:
os.remove(path)
delAll(path)
table = tree
items = table.get_children()
[table.delete(item) for item in items]
wintree = WinTree(xuanzhe_win_path[0], win_path, tree)
wintree.show_wenjian()
except:
showinfo("错误提示", "未选择路径!")
win_delete_wenjian_but = tk.Button(self.bommot_frame_left, text="删除文件", font=("宋体", 13), command=win_wenjian_delete_button, relief="flat")
win_delete_wenjian_but.place(x=115, y=35)
# 上传文件
def shangchaung(self, ftp_path, ftp_list, win_path, bommot_frame_center, tree_ftp):
def shangchaung_button():
try:
def uploadfile(ftp, remotepath, localpath):
bufsize = 1024
fp = open(localpath, 'rb')
ftp.storbinary(r'STOR ' + rf'{remotepath}', fp, bufsize) # 上传文件
ftp.set_debuglevel(0)
fp.close()
print(ftp_list[0], ftp_list[0].pwd()+"\\"+win_path[0].split("\\")[-1], win_path[0], "----------==============-----------------==========")
uploadfile(ftp_list[0], ftp_list[0].pwd()+"\\"+win_path[0].split("\\")[-1], win_path[0])
# 更新进度条函数
def change_schedule(now_schedule, all_schedule):
canvas.coords(fill_rec, (5, 5, 6 + (now_schedule / all_schedule) * 100, 25))
bommot_frame_center.update()
x.set(str(round(now_schedule / all_schedule * 100, 2)) + '%')
if round(now_schedule / all_schedule * 100, 2) == 100.00:
x.set("完==成==了")
canvas = tk.Canvas(bommot_frame_center, width=110, height=30, bg="white")
canvas.place(x=150, y=25)
x = tk.StringVar()
# 进度条以及完成程度
out_rec = canvas.create_rectangle(5, 5, 105, 25, outline="blue", width=1)
fill_rec = canvas.create_rectangle(5, 5, 5, 25, outline="", width=0, fill="blue")
tk.Label(bommot_frame_center, textvariable=x, font=("宋体", 13)).place(x=280, y=30)
for i in range(100):
change_schedule(i, 99)
if str(ftp_list[0].pwd()) != "/":
table = tree_ftp
items = table.get_children()
[table.delete(item) for item in items]
ftptree = FtpTree(ftp_path, ftp_list, tree_ftp)
ftptree.xianshi(ftp_list[0].pwd())
else:
table = tree_ftp
items = table.get_children()
[table.delete(item) for item in items]
ftptree = FtpTree(ftp_path, ftp_list, tree_ftp)
ftptree.xianshi("/")
except:
showinfo("错误提示", "本地路径或服务器连接异常!")
shangchaung_but = tk.Button(self.bommot_frame_left, text="上传文件", font=("宋体", 13), command=shangchaung_button, relief="flat")
shangchaung_but.place(x=220, y=2)
# 打开文件
def open_wenjian(self, win_path):
def win_open_wenjian_button():
try:
os.startfile(rf"{win_path[0]}")
except:
showinfo("错误提示", "未选择路径!")
win_open_wenjian_but = tk.Button(self.bommot_frame_left, text="打开文件", font=("宋体", 13), command=win_open_wenjian_button, relief="flat")
win_open_wenjian_but.place(x=220, y=35)
def gexian(self):
tk.Label(self.bommot_frame_left, text="w|\ni|\nn|", font=("宋体", 13)).place(x=330, y=1)
import tkinter as tk
from tkinter.messagebox import showinfo
from ftp_client_alter_bug.tree.ftp_tree import FtpTree
from ftp_client_alter_bug.tree.win_tree import WinTree
class BottomMenuBarRight:
def __init__(self, bommot_frame_right):
self.bommot_frame_right = bommot_frame_right
# 隔板
def geban(self):
tk.Label(self.bommot_frame_right, text="|f\n|t\n|p", font=("宋体", 13), relief="flat").place(x=-5, y=5)
# 创建目录
def ftp_chaungjian_mulu(self, ftp_path, ftp_list, tree_ftp):
def ftp_cj_mulu_button():
cj_win = tk.Tk()
cj_win.geometry("300x200")
titlte_lab = tk.Label(cj_win, text="创建目录", font=("宋体", 18))
titlte_lab.place(x=105, y=25)
titlte_lab = tk.Label(cj_win, text="目录名:", font=("宋体", 13))
titlte_lab.place(x=30, y=80)
cj_entry = tk.Entry(cj_win, width=21)
cj_entry.place(x=100, y=80)
def cj_button():
try:
muluzhi = str(cj_entry.get()).encode()
ftp_list[0].mkd(muluzhi.decode())
print(ftp_path)
except:
showinfo("错误提示", "路径选择或服务器连接异常!")
finally:
cj_win.destroy()
if str(ftp_list[0].pwd()) != "/":
table = tree_ftp
items = table.get_children()
[table.delete(item) for item in items]
ftptree = FtpTree(ftp_path, ftp_list, tree_ftp)
ftptree.xianshi(ftp_list[0].pwd())
# cj_win.destroy()
else:
table = tree_ftp
items = table.get_children()
[table.delete(item) for item in items]
ftptree = FtpTree(ftp_path, ftp_list, tree_ftp)
ftptree.xianshi("/")
# cj_win.destroy()
cj_but = tk.Button(cj_win, text="确=======================认", font=("宋体", 13), command=cj_button)
cj_but.place(x=20, y=130)
cj_win.mainloop()
ftp_cj_mulu_but = tk.Button(self.bommot_frame_right, text="创建目录", font=("宋体", 13), relief="flat", command=ftp_cj_mulu_button)
ftp_cj_mulu_but.place(x=40, y=2)
# 进入下级
def ftp_jinru_xj(self, ftp_path, ftp_list, tree_ftp):
def ftp_jinru_xj_button():
try:
global path
path = ftp_path[0]
table = tree_ftp
items = table.get_children()
[table.delete(item) for item in items]
ftptree = FtpTree(ftp_path, ftp_list, tree_ftp)
ftptree.xianshi(ftp_path[0])
except:
showinfo("错误提示", "路径选择或服务器连接异常!")
global a
a = ftp_jinru_xj_button
ftp_jinru_xj_but = tk.Button(self.bommot_frame_right, text="进入下级", font=("宋体", 13), relief="flat", command=ftp_jinru_xj_button)
ftp_jinru_xj_but.place(x=40, y=35)
# 删除目录
def ftp_delete_mulu(self, ftp_path, ftp_list, tree_ftp):
def ftp_delete_mulu_button():
try:
ftp_list[0].rmd(ftp_path[0])
if str(ftp_list[0].pwd()) != "/":
table = tree_ftp
items = table.get_children()
[table.delete(item) for item in items]
ftptree = FtpTree(ftp_path, ftp_list, tree_ftp)
ftptree.xianshi(ftp_list[0].pwd())
else:
table = tree_ftp
items = table.get_children()
[table.delete(item) for item in items]
ftptree = FtpTree(ftp_path, ftp_list, tree_ftp)
ftptree.xianshi("/")
except:
showinfo("错误提示", "路径选择或服务器连接异常!")
ftp_delete_mulu_but = tk.Button(self.bommot_frame_right, text="删除目录", font=("宋体", 13), relief="flat", command=ftp_delete_mulu_button)
ftp_delete_mulu_but.place(x=150, y=2)
# 删除文件
def ftp_delete_wenjian(self, ftp_path, ftp_list, tree_ftp):
def ftp_delete_wenjian_button():
try:
ftp_list[0].delete(ftp_path[0])
if str(ftp_list[0].pwd()) != "/":
table = tree_ftp
items = table.get_children()
[table.delete(item) for item in items]
ftptree = FtpTree(ftp_path, ftp_list, tree_ftp)
ftptree.xianshi(ftp_list[0].pwd())
else:
table = tree_ftp
items = table.get_children()
[table.delete(item) for item in items]
ftptree = FtpTree(ftp_path, ftp_list, tree_ftp)
ftptree.xianshi("/")
except:
showinfo("错误提示", "路径选择或服务器连接异常!")
ftp_delete_wenjian_but = tk.Button(self.bommot_frame_right, text="删除文件", font=("宋体", 13), relief="flat", command=ftp_delete_wenjian_button)
ftp_delete_wenjian_but.place(x=150, y=35)
# 下载文件
def xiazai(self, ftp_list, ftp_path, win_path, xuanzhe_win_path, bommot_frame_center, tree):
def xiazai_button():
try:
print(ftp_list[0], ftp_path[0], win_path[0], "三个路径————————")
def downloadfile(ftp, remotepath, localpath):
bufsize = 1024 # 设置缓冲块大小
fp = open(localpath, 'wb') # 以写模式在本地打开文件
ftp.retrbinary('RETR ' + remotepath, fp.write, bufsize) # 接收服务器上文件并写入本地文件
ftp.set_debuglevel(0) # 关闭调试
fp.close() # 关闭文件
downloadfile(ftp_list[0], ftp_path[0], win_path[0]+"\\"+ftp_path[0].split("/")[-1])
# 更新进度条函数
def change_schedule(now_schedule, all_schedule):
canvas.coords(fill_rec, (5, 5, 6 + (now_schedule / all_schedule) * 100, 25))
bommot_frame_center.update()
x.set(str(round(now_schedule / all_schedule * 100, 2)) + '%')
if round(now_schedule / all_schedule * 100, 2) == 100.00:
x.set("完==成==了")
canvas = tk.Canvas(bommot_frame_center, width=110, height=30, bg="white")
canvas.place(x=150, y=25)
x = tk.StringVar()
# 进度条以及完成程度
out_rec = canvas.create_rectangle(5, 5, 105, 25, outline="blue", width=1)
fill_rec = canvas.create_rectangle(5, 5, 5, 25, outline="", width=0, fill="blue")
tk.Label(bommot_frame_center, textvariable=x, font=("宋体", 13)).place(x=280, y=30)
for i in range(100):
change_schedule(i, 99)
table = tree
items = table.get_children()
[table.delete(item) for item in items]
wintree = WinTree(xuanzhe_win_path[0], win_path, tree)
wintree.show_wenjian()
print(win_path[0]+ftp_path[0].split("\\")[-1],"============================")
except:
showinfo("错误提示", "路径选择或服务器连接异常!")
xiazai_but = tk.Button(self.bommot_frame_right, text="下载文件", font=("宋体", 13), relief="flat", command=xiazai_button)
xiazai_but.place(x=250, y=2)
# 返回上级
def ftp_fh_sj(self, ftp_path, ftp_list, tree_ftp):
def ftp_fh_sj_button():
try:
table = tree_ftp
items = table.get_children()
[table.delete(item) for item in items]
ftptree = FtpTree(ftp_path, ftp_list, tree_ftp)
ftptree.xianshi("..")
except:
showinfo("错误提示", "路径选择或服务器连接异常!")
global b
b = ftp_fh_sj_button
ftp_fh_sj_but = tk.Button(self.bommot_frame_right, text="返回上级", font=("宋体", 13), relief="flat", command=ftp_fh_sj_button)
ftp_fh_sj_but.place(x=250, y=35)
import os
from tkinter import ttk
import tkinter as tk
class FtpSearch:
def __init__(self, tree_ftp, search_name, ftp_search_path, win_tree):
self.ftp = tree_ftp
# 搜索框的内容
self.search_name = search_name
self.ftp_search_path = ftp_search_path
self.tree = win_tree
# # 滚动条
# sy = tk.Scrollbar(self.center_frame)
# sy.pack(side=tk.RIGHT, fill=tk.Y)
# sy.config(command=self.tree.yview)
# self.tree.config(yscrollcommand=sy.set)
# 绑定事件
self.tree.bind("<>" , self.func)
self.tree.pack(expand=True, fill=tk.BOTH)
self.ev = tk.Variable()
def show(self):
dir_res = []
self.ftp.dir('.', dir_res.append)
for i in dir_res:
print(i)
if self.search_name in i.split()[3]:
self.tree.insert("", "end", text=i.split()[3], open=True, values=(i.split()[3]))
def func(self, event):
# widget触发事件的构建
self.v = event.widget.selection()
for sv in self.v:
file = self.tree.item(sv)["text"]
self.ev.set(file)
apath = self.tree.item(sv)["values"][0]
self.ftp_search_path.clear()
self.ftp_search_path.append(apath)
print(self.ftp_search_path)
print(apath)
import os
from tkinter import ttk
import tkinter as tk
class WinSearch:
def __init__(self, search_path, search_name, win_search_path, win_tree):
self.search_path = search_path
# 搜索框的内容
self.search_name = search_name
self.win_search_path = win_search_path
self.tree = win_tree
# # 滚动条
# sy = tk.Scrollbar(self.center_frame)
# sy.pack(side=tk.RIGHT, fill=tk.Y)
# sy.config(command=self.tree.yview)
# self.tree.config(yscrollcommand=sy.set)
# 绑定事件
self.tree.bind("<>" , self.func)
self.tree.pack(expand=True, fill=tk.BOTH)
self.ev = tk.Variable()
# 搜索关键词目录
def search_keyword_dirs(self, root1, dirs):
for _dir in dirs:
if -1 != _dir.find(self.search_name) and _dir[0] != '$':
AllDir = os.path.join(root1, _dir)
self.tree.insert("", "end", text=AllDir, values=(AllDir,))
# 搜索关键词文件
def search_keyword_files(self, root, files):
for file in files:
if self.search_name in file:
AllFile = os.path.join(root, file)
self.tree.insert("", "end", text=AllFile, values=(AllFile,))
# 搜索
def search(self):
curdisks = self.search_path
# root 当前正在遍历的这个文件夹的本身的地址
# dirs 是一个 list ,内容是该文件夹中所有的目录的名字
# files 同样是 list , 内容是该文件夹中所有的文件
for root, dirs, files in os.walk(curdisks):
self.search_keyword_dirs(root, dirs)
self.search_keyword_files(root, files)
def func(self, event):
# widget触发事件的构建
self.v = event.widget.selection()
for sv in self.v:
file = self.tree.item(sv)["text"]
self.ev.set(file)
apath = self.tree.item(sv)["values"][0]
self.win_search_path.clear()
self.win_search_path.append(apath)
print(self.win_search_path)
print(apath)
import pickle
import tkinter as tk
from tkinter import ttk
from tkinter.messagebox import showinfo
from ftp_client_alter_bug.seek.ftp_search import FtpSearch
from ftp_client_alter_bug.seek.win_search import WinSearch
from ftplib import FTP
import tkinter.filedialog as fi
from ftp_client_alter_bug.tree.ftp_tree import FtpTree
from ftp_client_alter_bug.tree.win_tree import WinTree
class TopMenuBar:
def __init__(self, top_frame, path, win, win_search_path, ftp_list, xuanzhe_win_path):
self.top_frame = top_frame
self.path = path
self.win = win
self.win_search_path = win_search_path
self.ftp_list = ftp_list
self.xuanzhe_win_path = xuanzhe_win_path
# logo
def logo(self):
logo_lable = tk.Label(self.top_frame, text="FTP客户端", font=("华文彩云", 29), fg="green")
logo_lable.place(x=5, y=10)
# window目录选择按钮
def local_mulu(self, win_path, tree):
# 目录选择按钮的回调函数
def mulu_button():
self.xuanzhe_win_path.clear()
DEF_PATH = ""
newDir = fi.askdirectory(initialdir=DEF_PATH, title="打开目录")
print(newDir)
DEF_PATH = newDir
if len(newDir) == 0:
return
print(DEF_PATH)
self.xuanzhe_win_path.append(DEF_PATH)
print(self.xuanzhe_win_path)
table = tree
items = table.get_children()
[table.delete(item) for item in items]
wintree = WinTree(self.xuanzhe_win_path[0], win_path, tree)
wintree.show_wenjian()
mulu_but = tk.Button(self.top_frame, text="选择本地目录", font=("宋体", 13), command=mulu_button, relief="flat")
mulu_but.place(x=220, y=5)
# 打开文件按钮
def open_wenjian(self):
def open_wenjian_button():
pass
open_wenjian_but = tk.Button(self.top_frame, text="选择本地文件", font=("宋体", 13), command=open_wenjian_button, relief="flat")
open_wenjian_but.place(x=220, y=30)
# 搜索框和其按钮
def search_box(self, win_search_name, win_search_tree, ftp_search_path, ftp_list):
# 本地搜索按钮的回调函数
def local_search_button():
try:
win_search_name.clear()
win_name = search_entry.get()
win_search_name.append(win_name)
table = win_search_tree[0]
items = table.get_children()
[table.delete(item) for item in items]
winsearch = WinSearch(self.xuanzhe_win_path[0], win_name, self.win_search_path, win_search_tree[0])
winsearch.search()
except:
showinfo("错误提示", "本地路径异常!")
# ftp搜索按钮的回调函数
def ftp_search_button():
try:
win_search_name.clear()
win_name = search_entry.get()
win_search_name.append(win_name)
table = win_search_tree[0]
items = table.get_children()
[table.delete(item) for item in items]
ftpsearch = FtpSearch(ftp_list[0], win_name, ftp_search_path, table)
ftpsearch.show()
except:
showinfo("错误提示", "服务器连接异常!")
search_entry = tk.Entry(self.top_frame, width="21", font=("宋体", 15))
search_entry.place(x=475, y=17)
window_search = tk.Button(self.top_frame, text="本地搜索", font=("宋体", 15), command=local_search_button, relief="flat")
window_search.place(x=350, y=17)
ftp_search = tk.Button(self.top_frame, text="ftp搜索", font=("宋体", 15), command=ftp_search_button, relief="flat")
ftp_search.place(x=730, y=17)
# ip,port显示
def name_ip(self, bieming, ip):
name = bieming
name_lable = tk.Label(self.top_frame, text=f"user: {name}", font=("宋体", 13))
name_lable.place(x=850, y=5)
ip = ip
ip_lable = tk.Label(self.top_frame, text=f"ip: {ip}", font=("宋体", 13))
ip_lable.place(x=1030, y=5)
# 退出登录按钮
def exit_login(self, ftp_tree_list, ftp_path, ftp_list):
def exit_button():
self.ftp_list[0].quit()
table = ftp_tree_list[0]
items = table.get_children()
[table.delete(item) for item in items]
ftptree = FtpTree(ftp_path, ftp_list, ftp_tree_list[0])
ftptree.xianshi("/")
exit_but = tk.Button(self.top_frame, text="退出登录", font=("宋体", 13), command=exit_button, relief="flat")
exit_but.place(x=1100, y=30)
# 登录按钮
def login_in(self, ftp_path, ftp_list, ftp_tree_list):
def login_in_button():
wind = tk.Tk()
wind.geometry("400x370")
titile_lab = tk.Label(wind, text="ftp登录", font=("宋体", 19))
titile_lab.place(x=150, y=30)
self.ftp_list.clear()
bieming_lab = tk.Label(wind, text="别名:", font=("宋体", 15))
bieming_lab.place(x=60, y=90)
bieming_entry = tk.Entry(wind, font=("宋体", 15))
bieming_entry.place(x=130, y=90)
user_name_lab = tk.Label(wind, text="用户名:", font=("宋体", 15))
user_name_lab.place(x=40, y=130)
user_name_entry = tk.Entry(wind, font=("宋体", 15))
user_name_entry.place(x=130, y=130)
pass_name_lab = tk.Label(wind, text="密码:", font=("宋体", 15))
pass_name_lab.place(x=60, y=170)
pass_name_entry = tk.Entry(wind, font=("宋体", 15))
pass_name_entry.place(x=130, y=170)
ip_name_lab = tk.Label(wind, text="ip:", font=("宋体", 15))
ip_name_lab.place(x=80, y=210)
ip_name_entry = tk.Entry(wind, font=("宋体", 15))
ip_name_entry.place(x=130, y=210)
port_name_lab = tk.Label(wind, text="port:", font=("宋体", 15))
port_name_lab.place(x=60, y=250)
port_name_entry = tk.Entry(wind, font=("宋体", 15))
port_name_entry.place(x=130, y=250)
def d_button():
self.ftp_list.clear()
bieming = str(bieming_entry.get())
user_name = str(user_name_entry.get())
pass_name = str(pass_name_entry.get())
ip_name = str(ip_name_entry.get())
port_name = int(port_name_entry.get())
try:
# 打开被序列化文件
with open("../data/usr_info.pickle", "wb") as usr_file:
# 用户数据
usr_info = [bieming, user_name, pass_name, ip_name, port_name]
# 存储(序列化)数据
pickle.dump(usr_info, usr_file)
except FileNotFoundError:
print("存储错误")
self.name_ip(bieming, ip_name)
self.ftp = FTP() # 设置变量
self.ftp.connect(ip_name, port_name) # 连接的ftp sever和端口
self.ftp.login(user_name, pass_name) # 连接的用户名,密码
self.ftp.encoding = 'GB18030'
self.ftp_list.append(self.ftp)
table = ftp_tree_list[0]
items = table.get_children()
[table.delete(item) for item in items]
ftptree = FtpTree(ftp_path, ftp_list, ftp_tree_list[0])
ftptree.xianshi("/")
wind.destroy()
d_but = tk.Button(wind, text="登=======================录", font=("宋体", 15), command=d_button)
d_but.place(x=60, y=310)
wind.mainloop()
login_in_but = tk.Button(self.top_frame, text="登录", font=("宋体", 13), command=login_in_button, relief="flat")
login_in_but.place(x=850, y=30)
# 历史登录
def lishi_login_in(self, ftp_path, ftp_list, ftp_tree_list):
def lishi_login_button():
self.ftp_list.clear()
try:
# 打开被序列化文件,会自动创建此文件
with open("../data/usr_info.pickle", "rb+") as usr_file:
# 读取被序列化的文件
global usr_info
usr_info = pickle.load(usr_file)
print(usr_info)
except FileNotFoundError:
print("读取错误")
self.name_ip(usr_info[0], usr_info[3])
self.ftp = FTP() # 设置变量
self.ftp.connect(usr_info[3], usr_info[4]) # 连接的ftp sever和端口
self.ftp.login(usr_info[1], usr_info[2]) # 连接的用户名,密码
self.ftp.encoding = 'GB18030'
self.ftp_list.append(self.ftp)
table = ftp_tree_list[0]
items = table.get_children()
[table.delete(item) for item in items]
ftptree = FtpTree(ftp_path, ftp_list, ftp_tree_list[0])
ftptree.xianshi("/")
lishi_login_but = tk.Button(self.top_frame, text="历史登录", font=("宋体", 13), command=lishi_login_button, relief="flat")
lishi_login_but.place(x=950, y=30)
import os
import tkinter as tk
from tkinter import ttk
from ftplib import FTP # 加载ftp模块
import sys
class FtpTree:
def __init__(self, ftp_path, ftp_list, tree_ftp):
self.tree = tree_ftp
self.num = 0
self.ftp_list = ftp_list
self.ftp_path = ftp_path
# # 滚动条
# sy = tk.Scrollbar(self.right_frame)
# sy.pack(side=tk.LEFT, fill=tk.Y)
# sy.config(command=self.tree.yview)
# self.tree.config(yscrollcommand=sy.set)
# 绑定事件
self.tree.bind("<>" , self.func)
self.tree.pack(expand=True, fill=tk.BOTH)
self.ev = tk.Variable()
print(self.ev)
def xianshi(self, path_ftp):
self.ftp = self.ftp_list[0]
self.ftp.cwd(path_ftp)
self.num += 1
dir_res = []
self.ftp.dir('.', dir_res.append)
for i in dir_res:
if i.split()[2] == "" :
self.tree.insert("", "end", text=i.split()[3], open=True, values=(i.split()[0], i.split()[2]))
else:
self.tree.insert("", "end", text=i.split()[3], open=True, values=(i.split()[0], "" ))
def func(self, event):
# widget触发事件的构建
self.v = event.widget.selection()
for sv in self.v:
self.file = self.tree.item(sv)["text"]
self.ev.set(self.file)
self.ftp_path.clear()
self.ftp_path.append(self.file)
print(self.ftp_path)
print(self.file)
import os
import tkinter as tk
from tkinter import ttk
class WinTree:
def __init__(self, path, win_path, tree):
self.path = path
self.win_path = win_path
self.tree = tree
# # 滚动条
# sy = tk.Scrollbar(self.left_frame)
# sy.pack(side=tk.RIGHT, fill=tk.Y)
# sy.config(command=self.tree.yview)
# self.tree.config(yscrollcommand=sy.set)
# 绑定事件
self.tree.bind("<>" , self.func)
self.tree.pack(expand=True, fill=tk.BOTH)
self.ev = tk.Variable()
print(self.ev)
def show_wenjian(self):
self.root = self.tree.insert("", "end", text=self.getlastpath(self.path, ), open=True, values=(self.path,))
self.loadtree(self.root, self.path)
def func(self, event):
# widget触发事件的构建
self.v = event.widget.selection()
for sv in self.v:
file = self.tree.item(sv)["text"]
self.ev.set(file)
apath = self.tree.item(sv)["values"][0]
self.win_path.clear()
self.win_path.append(apath)
print(self.win_path)
print(apath)
def loadtree(self, parent, parentPath):
for FileName in os.listdir(parentPath):
absPath = os.path.join(parentPath, FileName)
if ("$" in absPath) == False:
# 插入树枝
treey = self.tree.insert(parent, "end", text=self.getlastpath(absPath), values=(absPath, ))
# 判断是否是目录
if os.path.isdir(absPath):
self.loadtree(treey, absPath)
def getlastpath(self, path):
pathList = os.path.split(path)
return pathList[-1]
from tkinter.messagebox import showinfo
import windnd
import tkinter as tk
from ftp_client_alter_bug.tree.ftp_tree import FtpTree
class FtpDrag():
def __init__(self, right_frame, ftp_path, ftp_list, win_path, bommot_frame_center, tree_ftp):
self.right_frame = right_frame
self.ftp_path = ftp_path
self.ftp_list = ftp_list
self.win_path = win_path
self.bommot_frame_center = bommot_frame_center
self.tree_ftp = tree_ftp
def win_file(self, files):
msg = "\n".join((item.decode("gbk") for item in files))
print(msg)
# with open(msg, mode="rb+") as re:
# buffer = re.read()
# with open(self.win_path[0] + "\\" + msg.split("\\")[-1], mode="wb+") as wr:
# wr.write(buffer)
try:
def uploadfile(ftp, remotepath, localpath):
bufsize = 1024
fp = open(localpath, 'rb')
ftp.storbinary(r'STOR ' + rf'{remotepath}', fp, bufsize) # 上传文件
ftp.set_debuglevel(0)
fp.close()
uploadfile(self.ftp_list[0], self.ftp_list[0].pwd() + "\\" + msg.split("\\")[-1], msg)
# 更新进度条函数
def change_schedule(now_schedule, all_schedule):
canvas.coords(fill_rec, (5, 5, 6 + (now_schedule / all_schedule) * 100, 25))
self.bommot_frame_center.update()
x.set(str(round(now_schedule / all_schedule * 100, 2)) + '%')
if round(now_schedule / all_schedule * 100, 2) == 100.00:
x.set("完==成==了")
canvas = tk.Canvas(self.bommot_frame_center, width=110, height=30, bg="white")
canvas.place(x=150, y=25)
x = tk.StringVar()
# 进度条以及完成程度
out_rec = canvas.create_rectangle(5, 5, 105, 25, outline="blue", width=1)
fill_rec = canvas.create_rectangle(5, 5, 5, 25, outline="", width=0, fill="blue")
tk.Label(self.bommot_frame_center, textvariable=x, font=("宋体", 13)).place(x=280, y=30)
for i in range(100):
change_schedule(i, 99)
if str(self.ftp_list[0].pwd()) != "/":
table = self.tree_ftp
items = table.get_children()
[table.delete(item) for item in items]
ftptree = FtpTree(self.ftp_path, self.ftp_list, self.tree_ftp)
ftptree.xianshi(self.ftp_list[0].pwd())
else:
table = self.tree_ftp
items = table.get_children()
[table.delete(item) for item in items]
ftptree = FtpTree(self.ftp_path, self.ftp_list, self.tree_ftp)
ftptree.xianshi("/")
except:
showinfo("错误提示", "服务器连接异常!")
def execute(self):
windnd.hook_dropfiles(self.right_frame, func=self.win_file)
from tkinter.messagebox import showinfo
import windnd
from ftp_client_alter_bug.tree.win_tree import WinTree
class WinDrag():
def __init__(self, left_frame, win_path, xuanzhe_win_path, tree):
self.left_frame = left_frame
self.win_path = win_path
self.xuanzhe_win_path = xuanzhe_win_path
self.tree = tree
def win_file(self, files):
msg = "\n".join((item.decode("gbk") for item in files))
print(msg)
try:
with open(msg, mode="rb+") as re:
buffer = re.read()
with open(self.win_path[0] + "\\" + msg.split("\\")[-1], mode="wb+") as wr:
wr.write(buffer)
table = self.tree
items = table.get_children()
[table.delete(item) for item in items]
wintree = WinTree(self.xuanzhe_win_path[0], self.win_path, self.tree)
wintree.show_wenjian()
except:
showinfo("错误提示", "未选择本地路径!")
def execute(self):
windnd.hook_dropfiles(self.left_frame, func=self.win_file)