Python Tkinter 聊天室程序:使用多线程实现实时聊天功能
导入必要的模块
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() # 进入登录窗口的主循环
原文地址: http://www.cveoy.top/t/topic/nQlK 著作权归作者所有。请勿转载和采集!