这一篇教程,我们在之前已编写模块的基础上,通过wxPython实现GUI图形界面的客户端。
一、导入模块
我们需要导入之前server模块和client模块中实现的一些类和方法,另外还需要导入wx模块。
示例代码:
1
2
3
4
5
6
7
8
9
10
11 1'''
2想要学习Python?Python学习交流群:984632579满足你的需求,资料都已经上传群文件,可以自行下载!
3'''
4from pclient import random_string # 导入获取随机密钥的方法
5from pserver import Node, UNHANDLED # 导入节点类和请求状态变量
6from xmlrpc.client import ServerProxy, Fault
7from threading import Thread
8from time import sleep
9import wx # 导入wxPython模块
10import sys
11
二、创建变量
变量与CMD客户端是一样的。
示例代码:
1
2
3 1HEAD_START = 0.1
2SECRET_LENGTH = 10
3
三、定义客户端类(Client)
在这个类中,我们需要完成以下三个方面:
- 服务器、服务器代理以及GUI界面初始化。
- 定义GUI图形界面。
- 定义下载事件的处理方法。
示例代码:
1
2
3
4
5
6
7
8
9
10 1class Client(wx.App): # 定义客户端类
2 def __init__(self, url_file, dir_name, url): # 定义构造方法
3 pass
4
5 def OnInit(self): # 重写超类初始化界面的方法
6 pass
7
8 def fetchHandler(self, event): # 定义下载事件的处理方法
9 pass
10
接下来,就逐一完成这些内容。
1、定义构造方法。
在构造方法中主要是启动GUI图形界面、启动服务器以及创建服务器代理对象。
这里需要注意的是,通过超类对象启动GUI界面。
示例代码:
1
2
3
4
5
6
7
8
9
10
11
12
13 1class Client(wx.App): # 定义客户端类
2 def __init__(self, url_file, dir_name, url): # 定义构造方法
3 super(Client, self).__init__() # 将Clint类的对象转换为超类的对象,能够运行OnInit()方法。
4 self.secret = random_string(SECRET_LENGTH)
5 node = Node(url, dir_name, self.secret)
6 thread = Thread(target=node._start)
7 thread.setDaemon(1)
8 thread.start()
9 sleep(HEAD_START)
10 self.server = ServerProxy(url)
11 for line in open(url_file):
12 self.server.hello(line.strip())
13
2、重写初始化GUI界面的方法。
这一部分内容大家可以参考之前我们讲过的wxPython部分。
示例代码:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19 1def OnInit(self): # 重写超类初始化界面的方法
2 window = wx.Frame(None, title='文件下载器', size=(400, 85)) # 创建程序主窗口
3 background = wx.Panel(window) # 创建功能面板
4 self.user_input = user_input = wx.TextCtrl(background) # 添加文本框控件
5
6 submit = wx.Button(background, label='下载', size=(80, 25)) # 添加下载按钮控件
7 submit.Bind(wx.EVT_BUTTON, self.fetchHandler) # 绑定下载事件处理方法
8
9 hbox = wx.BoxSizer() # 创建尺寸器
10 hbox.Add(user_input, proportion=1, flag=wx.ALL | wx.EXPAND, border=10) # 水平容器中添加文本框
11 hbox.Add(submit, flag=wx.TOP | wx.BOTTOM | wx.RIGHT, border=10) # 水平容器中添加下载按钮
12
13 vbox = wx.BoxSizer(wx.VERTICAL) # 创建垂直容器
14 vbox.Add(hbox, proportion=0, flag=wx.EXPAND) # 将水平容器添加到垂直容器
15
16 background.SetSizer(vbox) # 将垂直容器添加到尺寸器
17 window.Show() # 显示程序窗口
18 return True
19
3、定义下载事件的处理方法。
点击下载按钮时的事件由这个方法进行处理,主要是调用服务器代理对象的fetch()方法。
示例代码:
1
2
3
4
5
6
7
8
9 1def fetchHandler(self, event): # 定义下载事件的处理方法
2 filename = self.user_input.GetValue()
3 try:
4 self.server.fetch(filename, self.secret)
5 except Fault as f:
6 if f.faultCode != UNHANDLED:
7 raise
8 print('没有找到文件:', filename)
9
四、定义与启动主程序
主程序依然通过命令行启动。
示例代码:
1
2
3
4
5
6
7
8 1def main(): # 定义主程序函数
2 url_file, dir_name, url = sys.argv[1:]
3 client = Client(url_file, dir_name, url)
4 client.MainLoop()
5
6if __name__ == '__main__':
7 main()
8
到这里我们就完成了一个简单的GUI客户端的编写。
同样通过命令行启动多个客户端,然后尝试通过文件名下载文件。