python版 聊天软件

#! /usr/bin/python3.4

from tkinter import *
from tkinter.filedialog import askopenfilename
import time
from threading import Thread
import socket
import sys
import os.path
import process

#聊天实现类
class ChatClient(Thread):
    #构造函数
    def __init__(self):
        Thread.__init__(self)
        #提示信息输出
        self.__info_event=None
        #读取数据输出
        self.__out_event=None
        #创建套接字
        self.clientSock=socket.socket()
        #重用地址
        self.clientSock.setsockopt(socket.SOL_SOCKET,socket.SO_REUSEADDR,1)

    #返回提醒信息
    #info事件
    @property
    def info_event(self):
        return self.__info_event
    @info_event.setter
    def info_event(self,handler):
        self.__info_event=handler
    #info输出
    def info(self,content):
        if self.info_event!=None:
            self.info_event(content)
    #返回接收结果
    #out事件
    @property
    def out_event(self):
        return self.__out_event
    @out_event.setter
    def out_event(self,handler):
        self.__out_event=handler
    #out输出
    def out(self,content):
        if self.out_event!=None:
            self.out_event(content)

    #发送信息
    def send(self,content):
        if self.clientSock==None:
            self.info("已经断开连接")
            return -1
        if type(content) is str:
            content=content.encode()
        elif type(content) is bytes:
            pass
        else:
            self.info("发送信息类型错误")
            return -1
        try:
            self.clientSock.send(content)
            #self.info("已经发送信息")
            return 0
        except:
            self.info("丢失连接")
            return -1

    #接受信息
    def recv(self):
        recv_msg={}
        if self.clientSock==None:
            return
        fileobj=self.clientSock.makefile("rb")
        while True:
            try:
                line=fileobj.readline()
            except:
                return None
            if not len(line):
                return None
            elif line==b"\r\n":
                break
            else:
                #print(line)
                key,value=line.decode().strip().split(": ")
                recv_msg[key]=value
        if "Length" in recv_msg:
            length=int(recv_msg["Length"])
            recv_msg["Content"]=b""
            while length>0:
                r=fileobj.read(min(1024,length))
                length-=len(r)
                recv_msg["Content"]+=r
            fileobj.close()
        elif "Count" in recv_msg:
            count=int(recv_msg["Count"])
            #print(count)
            recv_msg["Content"]=b""
            while count>0:
                recv_msg["Content"]+=fileobj.readline()
                count-=1
            fileobj.close()

        return recv_msg

    def run(self):
        while True:
            recv_msg=self.recv()
            if recv_msg==None:
                break
            self.out(recv_msg)

    #连接chat服务器
    def connserver(self,servername,serverport):
        try:
            self.clientSock.connect((servername,serverport))
            #self.info("成功连接pchat服务器")
            return 0
        except BaseException as e:
            self.info("连接pchat服务器失败")
            return -1

    #断开连接
    def disconnserver(self):
        if self.clientSock!=None:
            self.clientSock.close()
            self.clientSock=None
        self.info("断开连接")
        return 0

#主界面类
class MainWindow(Tk):
    #构造函数
    def __init__(self,name,pwd,chatwith=None):
        Tk.__init__(self)
        #用户名属性
        self.username=name
        self.password=pwd
        self.chatwith=chatwith
        self.init()
        self.conn()

    def conn(self,host="127.0.0.1",port=1234):
        #初始化chatclient
        self.chatclient=ChatClient()
        #添加事件处理
        self.chatclient.info_event=self.info
        self.chatclient.out_event=self.out
        #连接
        r=self.chatclient.connserver(host,port)
        #开始接收服务器发送的数据
        self.chatclient.start()
        return r

    #属性用户名
    @property
    def username(self):
        return self.__username

    @username.setter
    def username(self,name):
        self.__username=name
    @property
    def password(self):
        return self.__password
    @password.setter
    def password(self,pwd):
        self.__password=pwd
    #属性 聊天对象
    @property
    def chatwith(self):
        return self.__chatwith
    @chatwith.setter
    def chatwith(self,name):
        self.__chatwith=name

    #初始化菜单
    def init_menu(self):
        menubar=Menu(self,bg="lightblue")
        self["menu"]=menubar
        sysmenu=Menu(menubar,bg="lightblue")
        menubar.add_cascade(label="系统",menu=sysmenu)
        #下拉菜单
        sysmenu.add_command(label="配置",command=self.clientConfigure)
        sysmenu.add_separator()
        sysmenu.add_command(label="登陆",command=self.login)
        sysmenu.add_command(label="注册",command=self.register)
        sysmenu.add_command(label="注销",command=self.outlogin)
        sysmenu.add_separator()
        sysmenu.add_command(label="结束",command=self.destroy)

    #设置标题
    def setTitle(self,name):
        self.title("【%s】PChat [%s]"%(self.username,name))

    #界面初始化
    def init(self):
        self.setTitle(self.chatwith)
        self.init_menu()

        left_frame=Frame(self)
        left_frame.pack(expand=YES,fill=BOTH,side=LEFT)
        right_frame=Frame(self)
        right_frame.pack(fill=Y,side=LEFT)
        self.friends_list=Listbox(right_frame,bg="lightblue")
        self.friends_list.pack(expand=YES,fill=BOTH)
        self.friends_list.bind("",self.select_friend)
        self.friend_entry=Entry(right_frame)
        self.friend_entry.pack(fill=X)
        self.flush_button=Button(right_frame,text="刷新",command=self.flush)
        self.flush_button.pack(side=LEFT)
        self.add_button=Button(right_frame,text="增加",command=self.add)
        self.add_button.pack(side=LEFT)
        self.delete_button=Button(right_frame,text="删除",command=self.delete)
        self.delete_button.pack(side=LEFT)

        text_frame=Frame(left_frame,bg="white")
        text_frame.pack(expand=YES,fill=BOTH)
        self.chatmessage_text=Text(text_frame,bg="lightblue")
        self.chatmessage_text.pack(expand=YES,fill=BOTH,side=LEFT)
        text_scroll_bar=Scrollbar(text_frame,command=self.chatmessage_text.yview,bg="lightblue")
        text_scroll_bar.pack(fill=Y,side=RIGHT)
        self.chatmessage_text.configure(yscrollcommand=text_scroll_bar.set)
        self.chatmessage_text.tag_config("header",foreground="green",font=("Arial",15))
        self.chatmessage_text.tag_config("information",foreground="red",font=("Arial",10))
        self.chatmessage_text.tag_config("file",foreground="yellow",font=("Arial",18))
        self.chatmessage_text.tag_config("body",foreground="gray",font=("Arial",18))


        self.inputmessage_string=StringVar()
        self.inputmessage_entry=Entry(left_frame,bg="lightblue",textvariable=self.inputmessage_string)
        self.inputmessage_entry.pack(fill=X)
        self.inputmessage_entry.bind("",self.send)
        self.send_button=Button(left_frame,text="发送",command=self.send,bg="lightblue")
        self.send_button.pack(side=LEFT)

        self.send_file_button=Button(left_frame,text="发送文件",command=self.sendfile)
        self.send_file_button.pack(side=LEFT)

        self.bottom_frame=Frame(self)
        self.bottom_frame.pack(side=TOP,fill=X)

        #self.usersname_label=Label(self.bottom_frame,text="用户名:")
        #self.usersname_label.pack(side=LEFT)
        #添加关闭窗口的事件处理
        self.protocol("WM_DELETE_WINDOW",self.destroy)

    def select_friend(self,event=None):
        if len(event.widget.curselection()):
            chatwith=event.widget.get(event.widget.curselection()[0])
            if chatwith!="":
                self.chatwith=chatwith
                self.setTitle(self.chatwith)

你可能感兴趣的:(Python)