pythongui界面实例_python实现ftp服务器(使用wxpython实现GUI界面)

开发背景:

有时需要在局域网传输文件,总是要用U盘传输,要是多个人都需要同样的文件,U盘就有点麻烦了,Windows上的文件共享配置步骤很少,但是经常因为各种原因失败,又要检查来检查去的。于是考虑到通过FTP协议来传输文件,但是出名的FTP服务器软件类似Serv-U 这种,功能是很强大,但是配置也很多,我只是临时传输下文件,希望可以免安装,一键启动FTP,一键关闭FTP。于是就想使用python实现FTP服务器,再打包成exe文件。

开发环境:

win 7 64位,Python 3.6.2,pyftpdlib,wxpython,pyinstaller 3.3.1

具体思路:

通过pyftpdlib库实现FTP 功能ftpserver.py,使用wxpython实现GUI界面wxgui.py,在wxgui.py上生成配置文件config.ini,ftpserver.py再获取config.ini中的信息启动FTP,最后使用pyinstaller打包成exe可执行文件。

软件截图:

不过刚开发好的软件,应该有挺多BUG的,以后使用过程中再慢慢改进。

打开软件:

watermark,size_16,text_QDUxQ1RP5Y2a5a6i,color_FFFFFF,t_100,g_se,x_10,y_10,shadow_90,type_ZmFuZ3poZW5naGVpdGk=

选择FTP目录:

watermark,size_16,text_QDUxQ1RP5Y2a5a6i,color_FFFFFF,t_100,g_se,x_10,y_10,shadow_90,type_ZmFuZ3poZW5naGVpdGk=

启动FTP:

watermark,size_16,text_QDUxQ1RP5Y2a5a6i,color_FFFFFF,t_100,g_se,x_10,y_10,shadow_90,type_ZmFuZ3poZW5naGVpdGk=

关键步骤:

这次小项目中使用到了ini格式的配置文件,该配置文件提供给FTP服务启动需要的配置信息(是否匿名,FTP端口等),还可以记录FTP启动时GUI界面状态,使界面关闭后打开还是FTP启动时的界面。

ini 文件是文本文件,中间的数据格式一般为:

[Section1 Name]

KeyName1=value1

KeyName2=value2

...

python可以通过configparse内置模块写入读取配置信息

watermark,size_16,text_QDUxQ1RP5Y2a5a6i,color_FFFFFF,t_100,g_se,x_10,y_10,shadow_90,type_ZmFuZ3poZW5naGVpdGk=

该界面启动就执行下面的Python语句:

import configparse

config=configparser.ConfigParser()

config.add_section('ftpd')#添加一个新的section

config.set('ftpd','anonymous',str(not check.GetValue()))#判断复选框是否选中

config.set('ftpd','user',usertext.GetValue())#获取用户名

config.set('ftpd','password',passtext.GetValue())#获取密码

config.set('ftpd','port',porttext.GetValue())#获取端口

config.set('ftpd','dir',dirtext.GetValue())#获取目录

#写入到config.ini配置

with open('config.ini','w') as conf:

config.write(conf)

写入的配置文件config.ini如下:

[ftpd]

anonymous = False

user = aaa

password = aaa

port = 21

dir = E:\

接着就是ftpserver.py如何获取config.ini配置文件的信息了

config = configparser.ConfigParser()

config.read('config.ini')

config.get('ftpd',user)#获取用户名

config.get('ftpd',password)#获取密码

...

wxgui.py也可以通过config.ini配置文件来恢复程序界面关闭前的模样

def getconfig(v):#pyserver.py中的函数

#获取config.ini配置文件的信息

config = configparser.ConfigParser()

config.read('config.ini')

return config.get('ftpd',v)

if os.path.isfile('config.ini'):#config.ini文件存在的话,就获取配置文件信息。

if ftpserver.getconfig('anonymous')=='False':

check.SetValue(1)#设置复选框为选中状态

usertext.SetEditable(1)#允许编辑

passtext.SetEditable(1)

usertext.SetValue(ftpserver.getconfig('user'))#设置用户名输入框的值

passtext.SetValue(ftpserver.getconfig('password'))

porttext.SetValue(ftpserver.getconfig('port'))

dirtext.SetValue(ftpserver.getconfig('dir'))

具体源代码:

实现FTP功能代码ftpserver.py:

# coding:utf-8

from pyftpdlib.authorizers import DummyAuthorizer

from pyftpdlib.handlers import FTPHandler

from pyftpdlib.servers import FTPServer

import logging

import configparser

import os

def ftpd():

authorizer = DummyAuthorizer()

if getconfig('anonymous')=='True':

#添加匿名用户

authorizer.add_anonymous(getconfig('dir'),perm='elradfmwM')

else:

#添加用户,需要账号和密码登录

authorizer.add_user(getconfig('user'), getconfig('password'), getconfig('dir'), perm='elradfmwM')

handler = FTPHandler#初始化处理客户端命令的类

handler.authorizer = authorizer#选择登录方式(是否匿名)

logging.basicConfig(filename='ftpd.log', level=logging.INFO) #日志信息写入ftpd.log

address = ('0.0.0.0', getconfig('port'))#设置服务器的监听地址和端口

server = FTPServer(address, handler)

server.max_cons = 256 #给链接设置限制

server.max_cons_per_ip = 5

server.serve_forever() # 启动FTP

def getconfig(v):

#获取config.ini配置文件的信息

config = configparser.ConfigParser()

config.read('config.ini')

return config.get('ftpd',v)

if __name__ == '__main__':

ftpd()

实现GUI界面代码wxgui.py:

# -*- coding:utf-8 -*-

import wx

import os

import sys

import configparser

import ftpserver

import time

import threading

import socket

def onclick(event): #选择FTP目录

dlg=wx.DirDialog(window,'选择共享目录')

if dlg.ShowModal() == wx.ID_OK:

dirtext.SetValue(dlg.GetPath())

def onclose(event): #退出事件

if startbutton.GetLabel()=='关闭FTP':

dlg1 = wx.MessageDialog(None, "FTP正在运行,确认退出吗?", "退出", wx.YES_NO | wx.ICON_EXCLAMATION)

if dlg1.ShowModal()==wx.ID_YES:

sys.exit()

else:

sys.exit()

def startftp(event): #点击 启动FTP 按钮事件

global t

if startbutton.GetLabel()=='启动FTP':

startbutton.SetLabel('关闭FTP')

#把FTP启动信息写入config.ini配置文件中

config=configparser.ConfigParser()

config.add_section('ftpd')

config.set('ftpd','anonymous',str(not check.GetValue()))

config.set('ftpd','user',usertext.GetValue())

config.set('ftpd','password',passtext.GetValue())

config.set('ftpd','port',porttext.GetValue())

config.set('ftpd','dir',dirtext.GetValue())

with open('config.ini','w') as conf:

config.write(conf)

time.sleep(1)

#创建线程启动FTP

t=threading.Thread(target=ftpserver.ftpd)

t.setDaemon(True)

t.start()

iplist=socket.gethostbyname_ex(socket.gethostname())[2]

ftpurl=''

if iplist :

for ip in iplist:

ftpurl+='FTP地址:ftp://'+ip+':'+porttext.GetValue()+'\n'

urllabel.SetLabel(ftpurl)

else:

dlg1 = wx.MessageDialog(None, "FTP正在运行,确认退出吗?", "退出", wx.YES_NO | wx.ICON_EXCLAMATION)

if dlg1.ShowModal()==wx.ID_YES:

sys.exit()

def onchecked(event): #复选框事件

usertext.SetEditable(event.IsChecked())

passtext.SetEditable(event.IsChecked())

app = wx.App()#实例化wx.App

#创建顶级窗口,并且窗口不可改变尺寸

window = wx.Frame(None,title = "FTP服务器", size = (390, 260), pos=(400,300),style=wx.DEFAULT_FRAME_STYLE ^ wx.RESIZE_BORDER ^ wx.MAXIMIZE_BOX)

#绑定退出事件

window.Bind(wx.EVT_CLOSE,onclose)

#创建panel

panel = wx.Panel(window)

font = wx.Font(11, wx.SWISS, wx.NORMAL, wx.NORMAL)

#创建复选框,并绑定事件

check=wx.CheckBox(panel,-1,'使用账户密码登录',pos=(20,20),size=(200,-1))

check.SetFont(font)

window.Bind(wx.EVT_CHECKBOX,onchecked)

#创建静态文本和文本输入框

userlabel = wx.StaticText(panel, label = "用户名:", pos=(35,45))

userlabel.SetFont(font)

usertext = wx.TextCtrl(panel,-1,'',size=(95,20),pos=(90,42),style = wx.TE_READONLY)

passlabel = wx.StaticText(panel, label = "密码:",pos=(195,45))

passlabel.SetFont(font)

passtext = wx.TextCtrl(panel,-1,'',size=(95,20),pos=(235,42),style = wx.TE_PASSWORD)

passtext.SetEditable(False)

dirlabel = wx.StaticText(panel, label = "FTP目录:",pos=(23,72))

dirlabel.SetFont(font)

dirtext = wx.TextCtrl(panel,-1,os.getcwd(),size=(215,20),pos=(88,70),style = wx.TE_READONLY)

#创建按钮,并且绑定按钮事件

button=wx.Button(panel,-1,'更改',pos=(310,70),size=(40,20))

button.SetFont(wx.Font(9, wx.SWISS, wx.NORMAL, wx.NORMAL))

window.Bind(wx.EVT_BUTTON,onclick,button)

portlabel = wx.StaticText(panel, label = "FTP端口:",pos=(23,104))

portlabel.SetFont(font)

porttext = wx.TextCtrl(panel,-1,'21',size=(51,20),pos=(88,102))

startbutton=wx.Button(panel,-1,'启动FTP',pos=(160,130),size=(70,30))

startbutton.SetFont(wx.Font(12, wx.SWISS, wx.NORMAL, wx.NORMAL))

window.Bind(wx.EVT_BUTTON,startftp,startbutton)

#加载配置文件,使程序恢复到退出前的界面

if os.path.isfile('config.ini'):

if ftpserver.getconfig('anonymous')=='False':

check.SetValue(1)

usertext.SetEditable(1)

passtext.SetEditable(1)

usertext.SetValue(ftpserver.getconfig('user'))

passtext.SetValue(ftpserver.getconfig('password'))

porttext.SetValue(ftpserver.getconfig('port'))

dirtext.SetValue(ftpserver.getconfig('dir'))

urllabel = wx.StaticText(panel, label = "", pos=(80, 170))

urllabel.SetFont(font)

window.Show(True)#窗口可见

app.MainLoop() #主循环,处理事件

使用pyinstaller打包

如果顺利的话,两条命令就可以成功打包了,反正我是没那么顺利的了

pip安装pyinstaller

pip install pyinstaller

开始打包:

pyinstaller -F wxgui.py -w

-F 参数:是生成单个可执行文件

-w参数:因为我的是GUI程序,所以我使用这参数去掉命令行窗口

生成的文件:

watermark,size_16,text_QDUxQ1RP5Y2a5a6i,color_FFFFFF,t_100,g_se,x_10,y_10,shadow_90,type_ZmFuZ3poZW5naGVpdGk=

问题总结:

这次开发这个小项目中遇到了个问题,百度谷歌都找不到解决的办法。

程序创建个线程去启动FTP服务,当我想要停止FTP服务时,在不退出程序的情况下该如何去停止FTP服务?

问题已解决,把多线程换成多进程就可以了,多进程自带结束进程的方法

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值