最新消息:欢迎光临 魔力 • Python!大家可以点开导航菜单中的【学习目录】,这个目录类似图书目录,更加方便学习!

练习项目17:P2P在线文件共享(三)

Python教程 小楼一夜听春语 2174浏览 0评论

这一篇教程,我们在之前已编写模块的基础上,通过wxPython实现GUI图形界面的客户端。

一、导入模块

我们需要导入之前server模块和client模块中实现的一些类和方法,另外还需要导入wx模块。

示例代码:

from pclient import random_string  # 导入获取随机密钥的方法
from pserver import Node, UNHANDLED  # 导入节点类和请求状态变量
from xmlrpc.client import ServerProxy, Fault
from threading import Thread
from time import sleep
import wx  # 导入wxPython模块
import sys

二、创建变量

变量与CMD客户端是一样的。

示例代码:

HEAD_START = 0.1
SECRET_LENGTH = 10

三、定义客户端类(Client)

在这个类中,我们需要完成以下三个方面:

  • 服务器、服务器代理以及GUI界面初始化。
  • 定义GUI图形界面。
  • 定义下载事件的处理方法。

示例代码:

class Client(wx.App):  # 定义客户端类
    def __init__(self, url_file, dir_name, url):  # 定义构造方法
        pass

    def OnInit(self):  # 重写超类初始化界面的方法
        pass

    def fetchHandler(self, event):  # 定义下载事件的处理方法
        pass

接下来,就逐一完成这些内容。

1、定义构造方法。

在构造方法中主要是启动GUI图形界面、启动服务器以及创建服务器代理对象。

这里需要注意的是,通过超类对象启动GUI界面。

示例代码:

class Client(wx.App):  # 定义客户端类
    def __init__(self, url_file, dir_name, url):  # 定义构造方法
        super(Client, self).__init__()  # 将Clint类的对象转换为超类的对象,能够运行OnInit()方法。
        self.secret = random_string(SECRET_LENGTH)
        node = Node(url, dir_name, self.secret) 
        thread = Thread(target=node._start)
        thread.setDaemon(1)
        thread.start()
        sleep(HEAD_START)
        self.server = ServerProxy(url)
        for line in open(url_file):
            self.server.hello(line.strip())

2、重写初始化GUI界面的方法。

这一部分内容大家可以参考之前我们讲过的wxPython部分。

示例代码:

def OnInit(self):  # 重写超类初始化界面的方法
    window = wx.Frame(None, title='文件下载器', size=(400, 85))  # 创建程序主窗口
    background = wx.Panel(window)  # 创建功能面板
    self.user_input = user_input = wx.TextCtrl(background)  # 添加文本框控件

    submit = wx.Button(background, label='下载', size=(80, 25))  # 添加下载按钮控件
    submit.Bind(wx.EVT_BUTTON, self.fetchHandler)  # 绑定下载事件处理方法

    hbox = wx.BoxSizer()  # 创建尺寸器
    hbox.Add(user_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)  # 将水平容器添加到垂直容器

    background.SetSizer(vbox)  # 将垂直容器添加到尺寸器
    window.Show()  # 显示程序窗口
    return True

3、定义下载事件的处理方法。

点击下载按钮时的事件由这个方法进行处理,主要是调用服务器代理对象的fetch()方法。

示例代码:

def fetchHandler(self, event):  # 定义下载事件的处理方法
    filename = self.user_input.GetValue()
    try:
        self.server.fetch(filename, self.secret)
    except Fault as f:
        if f.faultCode != UNHANDLED:
            raise
        print('没有找到文件:', filename)

四、定义与启动主程序

主程序依然通过命令行启动。

示例代码:

def main():  # 定义主程序函数
    url_file, dir_name, url = sys.argv[1:]
    client = Client(url_file, dir_name, url)
    client.MainLoop()

if __name__ == '__main__':
    main()

到这里我们就完成了一个简单的GUI客户端的编写。

同样通过命令行启动多个客户端,然后尝试通过文件名下载文件。

本节练习源代码:【点此下载

转载请注明:魔力Python » 练习项目17:P2P在线文件共享(三)

头像
发表我的评论
取消评论

表情

Hi,您需要填写昵称和邮箱!

  • 昵称 (必填)
  • 邮箱 (必填)
  • 网站 (可选)