您的位置:首页 > 编程语言 > Python开发

9. Python脚本学习实战笔记九 文件共享GUI实现

2017-11-13 19:44 706 查看
9. Python脚本学习实战笔记九 文件共享GUI实现
本篇名言:“凡事顺其自然,遇事处于泰然,得意之时淡然,失意之时坦然,艰辛曲折必然,历尽沧桑悟然。”

针对第8个项目,使用GUI客户端进行扩展,让程序更加易用和人性化。

GUI客户端满足如下需求:

l  允许客户输入文件名,并将其提交到服务器端的fetch方法中

l  列出服务器文件目录中当前可用的文件

 

1.  用具和准备

安装了wxPython工具包。

完成了第8个项目。

2.  初次实现

Client使用wx.app的子类来替代上节中的cmd.CMD子类。

n  创建标题为FileSharing Client 的窗体

n  创建文本框

n  将文本框和按钮添加到窗体上,使用bos sizer布局

n  显示窗体,返回True,表示OnInit成功

导入了上节中实现的代码,代码实现如下:

 

from xmlrpclib import ServerProxy, Fault

from server import Node, UNHANDLED

from client import randomString

from threading import Thread

from time import sleep

from os import listdir

import sys

import wx

 

HEAD_START = 0.1 # Seconds

SECRET_LENGTH = 100

 

class Client(wx.App):

    """

    The main client class,which takes care of setting up the GUI and

    starts a Node for servingfiles.

    """

    def __init__(self, url,dirname, urlfile):

        """

        Creates a randomsecret, instantiates a Node with that secret,

        starts a Thread withthe Node's _start method (making sure the

        Thread is a daemon soit will quit when the application quits),

        reads all the URLs fromthe URL file and introduces the Node to

        them.

        """

        super(Client,self).__init__()

        self.secret =randomString(SECRET_LENGTH)

        n = Node(url, dirname,self.secret)

        t = Thread(target=n._start)

        t.setDaemon(1)

        t.start()

        # Give the server ahead start:

        sleep(HEAD_START)

        self.server =ServerProxy(url)

        for line inopen(urlfile):

            line = line.strip()

            self.server.hello(line)

 

 

    def OnInit(self):

        """

        Sets up the GUI.Creates a window, a text field, and a button, and

        lays them out. Bindsthe submit button to self.fetchHandler.

        """

 

        win = wx.Frame(None,title="File Sharing Client", size=(400, 45))

 

        bkg = wx.Panel(win)

 

        self.input = input =wx.TextCtrl(bkg);

 

        submit = wx.Button(bkg,label="Fetch", size=(80, 25))

       submit.Bind(wx.EVT_BUTTON, self.fetchHandler)

 

        hbox = wx.BoxSizer()

 

        hbox.Add(input,proportion=1, flag=wx.ALL | wx.EXPAND, border=10)

        hbox.Add(submit,flag=wx.TOP | wx.BOTTOM | wx.RIGHT, border=10)

 

        vbox =wx.BoxSizer(wx.VERTICAL)

        vbox.Add(hbox,proportion=0, flag=wx.EXPAND)

 

        bkg.SetSizer(vbox)

 

        win.Show()

 

        return True

 

    def fetchHandler(self,event):

        """

        Called when the userclicks the 'Fetch' button. Reads the

        query from the textfield, and calls the fetch method of the

        server Node. If thequery is not handled, an error message is

        printed.

        """

 

        query =self.input.GetValue()

        try:

           self.server.fetch(query, self.secret)

        except Fault, f:

            if f.faultCode !=UNHANDLED: raise

            print"Couldn't find the file", query

 

 

def main():

    urlfile, directory, url =sys.argv[1:]

    client = Client(url,directory, urlfile)

    client.MainLoop()

 

if __name__ == "__main__": main()

 

主要是通过wx.App类实现图形化。

执行如下:

E:\>python simple_guiclient.py urls.txtfiles1/  http://localhost:4242

E:\>python simple_guiclient.py urls.txtfiles2/  http://localhost:4243

 

3.  重构

每次初次实现都是那么不人性化,需要帮助用户查看自己可用的文件(程序启动时放置在文件目录内的以及后来从其他Node下载的)。

最后实现代码如下:

from xmlrpclib import ServerProxy, Fault

from server import Node, UNHANDLED

from client import randomString

from threading import Thread

from time import sleep

from os import listdir

import sys

import wx

 

HEAD_START = 0.1 # Seconds

SECRET_LENGTH = 100

 

 

class ListableNode(Node):

    """

    An extended version ofNode, which can list the files

    in its file directory.

    """

    def list(self):

        returnlistdir(self.dirname)

 

class Client(wx.App):

    """

    The main client class,which takes care of setting up the GUI and

    starts a Node for servingfiles.

    """

    def __init__(self, url,dirname, urlfile):

        """

        Creates a randomsecret, instantiates a ListableNode with that secret,

        starts a Thread with the ListableNode's_start method (making sure the

        Thread is a daemon soit will quit when the application quits),

        reads all the URLs fromthe URL file and introduces the Node to

        them. Finally, sets upthe GUI.

        """

        self.secret =randomString(SECRET_LENGTH)

        n = ListableNode(url,dirname, self.secret)

        t =Thread(target=n._start)

        t.setDaemon(1)

        t.start()

        # Give the server ahead start:

        sleep(HEAD_START)

        self.server =ServerProxy(url)

        for line inopen(urlfile):

            line = line.strip()

           self.server.hello(line)

        # Get the GUI going:

        super(Client,self).__init__()

 

    def updateList(self):

        """

        Updates the list boxwith the names of the files available

        from the server Node.

        """

       self.files.Set(self.server.list())

 

 

    def OnInit(self):

        """

        Sets up the GUI.Creates a window, a text field, a button, and

        a list box, and laysthem out. Binds the submit button to

        self.fetchHandler.

        """

 

        win = wx.Frame(None,title="File Sharing Client", size=(400, 300))

 

        bkg = wx.Panel(win)

 

        self.input = input =wx.TextCtrl(bkg);

 

        submit = wx.Button(bkg,label="Fetch", size=(80, 25))

       submit.Bind(wx.EVT_BUTTON, self.fetchHandler)

 

        hbox = wx.BoxSizer()

 

        hbox.Add(input,proportion=1, flag=wx.ALL | wx.EXPAND, border=10)

        hbox.Add(submit, flag=wx.TOP| wx.BOTTOM | wx.RIGHT, border=10)

 

        self.files = files =wx.ListBox(bkg)

        self.updateList()

 

        vbox =wx.BoxSizer(wx.VERTICAL)

        vbox.Add(hbox,proportion=0, flag=wx.EXPAND)

        vbox.Add(files,proportion=1,

                 flag=wx.EXPAND | wx.LEFT | wx.RIGHT| wx.BOTTOM, border=10)

 

        bkg.SetSizer(vbox)

 

        win.Show()

 

        return True

 

    def fetchHandler(self,event):

        """

        Called when the userclicks the 'Fetch' button. Reads the

        query from the text field, and calls thefetch method of the

        server Node. Afterhandling the query, updateList is called.

        If the query is nothandled, an error message is printed.

        """

        query =self.input.GetValue()

        try:

           self.server.fetch(query, self.secret)

            self.updateList()

 

        except Fault, f:

            if f.faultCode !=UNHANDLED: raise

            print"Couldn't find the file", query

 

def main():

    urlfile, directory, url = sys.argv[1:]

    client = Client(url,directory, urlfile)

    client.MainLoop()

 

if __name__ == '__main__': main()

 

执行如下:

E:\>python simple_guiclient.py urls.txtfiles1/  http://localhost:4242

E:\>python simple_guiclient.py urls.txtfiles2/  http://localhost:4243

执行如下:

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: