导入必要的模块

import tkinter as tk # GUI模块 import tkinter.messagebox # 弹窗模块 import socket # 网络通信模块 import datetime # 时间模块 import os # 系统模块 import threading # 多线程模块 import time # 时间模块

解析接收到的消息并构建展示格式

def analyze_and_build(raw): rawlist=raw.decode('utf-8').split('-$-') method=rawlist[0] if method=='n': time=datetime.datetime.fromtimestamp(float(rawlist[1])).strftime('%Y-%m-%d %H:%M:%S') name=rawlist[2] content=rawlist[3] return '%s %s: %s

' % (time,name,content) elif method=='e': time=datetime.datetime.fromtimestamp(float(rawlist[1])).strftime('%Y-%m-%d %H:%M:%S') name=rawlist[2] return '%s %s加入了聊天

' % (time,name) elif method=='q': name=rawlist[1] return '%s退出了聊天

' % name

进入主界面

def mainview(): name=nameEntry.get() host=hostEntry.get() port=portEntry.get() if name=='' or host=='' or port=='': tkinter.messagebox.showinfo(title='登录错误',message='参数不能为空!') else: s=socket.socket(socket.AF_INET,socket.SOCK_STREAM) # 创建套接字 s.connect((host,int(port))) # 连接服务器 loginWindow.destroy() # 销毁登录窗口 mainWindow=tk.Tk() # 创建主窗口 mainWindow.title('聊天室 - %s | %s:%s' % (name,host,port)) mainWindow.geometry('440x390')

    showText=tk.Text(mainWindow,height=20,width=60)  # 展示聊天记录的文本框
    emptyLabel=tk.Label(mainWindow,height=1)  # 分割线
    writeText=tk.Text(mainWindow,height=4,width=60)  # 编写消息的文本框
    showText.tag_config('red',foreground='red')  # 设置标签,用于后面标记自己发出的消息

    showText.pack()  # 放置展示文本框
    emptyLabel.pack()  # 放置分割线
    writeText.pack()  # 放置编辑文本框

    # 发送加入聊天室的请求
    s.send(('e-$-%s-$-%s' % (datetime.datetime.now().timestamp(),name)).encode('utf-8'))

    # 定义一个刷新聊天记录的函数
    def fresh():
        while True:
            data=s.recv(1024)
            rawlist=data.decode('utf-8').split('-$-')
            # 如果接收到的是自己发出的消息或加入聊天室的消息,则标记为红色
            if (rawlist[0]=='n' or rawlist[0]=='e') and rawlist[2]==name:
                showText.insert('end',analyze_and_build(data),'red')
            else:
                showText.insert('end',analyze_and_build(data))
            showText.see('end')  # 滚动到最后一行

    t1=threading.Thread(target=fresh)  # 创建一个线程来刷新聊天记录
    t1.start()

    # 定义发送消息的函数
    def send_message():
        data=writeText.get('0.0','end')  # 获取编辑框中的内容
        if data=='

': # 如果内容为空,则跳过 pass else: s.send(('n-$-%s-$-%s-$-%s' % (datetime.datetime.now().timestamp(),name,data)).encode('utf-8')) # 发送消息 writeText.delete('0.0','end') # 清空编辑框

    sendButton=tk.Button(mainWindow,text='发送',width=5,height=1,command=send_message)  # 发送按钮
    sendButton.pack()  # 放置发送按钮

    # 定义退出聊天室的函数
    def quit():
        s.send(('q-$-%s' % name).encode('utf-8'))  # 发送退出聊天室的请求
        time.sleep(0.5)  # 等待0.5秒
        s.send('_quitchatroom'.encode('utf-8'))  # 发送退出程序的请求
        mainWindow.destroy()  # 销毁主窗口
        os._exit(0)  # 退出程序

    mainWindow.protocol('WM_DELETE_WINDOW',quit)  # 捕捉关闭窗口事件
    mainWindow.mainloop()  # 进入主循环

创建登录窗口

loginWindow=tk.Tk() loginWindow.title('登录') loginWindow.geometry('200x250')

loginLabel=tk.Label(loginWindow, text='登录到聊天室', font=('Arial',15), width=10,height=2)

nameLabel=tk.Label(loginWindow, text='您的昵称(xiaoming):', font=('Arial',10), width=6,height=1)

hostLabel=tk.Label(loginWindow, text='主机(192.168.222.129):', font=('Arial',10), width=6,height=1)

portLabel=tk.Label(loginWindow, text='端口(63342):', font=('Arial',10), width=6,height=1)

nameEntry=tk.Entry(loginWindow) # 昵称输入框 hostEntry=tk.Entry(loginWindow) # 主机输入框 portEntry=tk.Entry(loginWindow) # 端口输入框

loginButton=tk.Button(loginWindow, text='登录', width=10, height=1, command=mainview) # 登录按钮

放置登录窗口中的各个控件

loginLabel.pack() nameLabel.pack() nameEntry.pack() hostLabel.pack() hostEntry.pack() portLabel.pack() portEntry.pack() loginButton.pack()

loginWindow.mainloop() # 进入登录窗口的主循环

Python Tkinter 聊天室程序:使用多线程实现实时聊天功能

原文地址: http://www.cveoy.top/t/topic/nQlK 著作权归作者所有。请勿转载和采集!

免费AI点我,无需注册和登录