Mikepython0721 发表于 2023-8-13 10:05

python聊天室3.0

本帖最后由 Mikepython0721 于 2023-8-13 13:07 编辑

python聊天室3.0重磅归来

一.前言
12月22日,我提出了一个想法,那就是实现Python聊天室!
后来在大家的帮助下完成了聊天室2.0版本,也是很感谢大家的支持!
距离2.0发布已经过了七个多月,现在也是放暑假了,有时间了继续干!!!!;www

二.程序内容+改进
该程序是基于python的socket库进行通信,tkinter库制作的GUI的程序

该程序目前实现了
    · 群聊功能
    · 查看历史聊天记录
    · 发送图片box

等功能

接下来会实现
    · 数据传输加密
    · 表情包发送
等功能

已知问题
    · 点击登录后可能卡死



另外,因为楼主mac卖掉了,所以之后都不会有mac版了:'(weeqw
这次的程序的服务端和客户端也是完成了一次重构,代码变得更有逻辑性,页面也变得更美观

三.程序运行截图





四.程序代码
服务端:
      from socket import *import threading
import time
import struct
import os



user = {}# 储存用户信息


def chatRecord(dataSocket):
    print("开始发送聊天记录")
    with open("Version 3.0\Liaotiainjjilu.txt", 'rb') as rf:
      # 持续读取文件并发送数据
      for data in rf:
            dataSocket.sendall(data)
    dataSocket.send("gaspatlazidbaafdsfaya".encode())
    print("聊天记录发送完成")
    time.sleep(0.5)

def imageChat(info, dataSocket):
    size_data = dataSocket.recv(4)# 以4个字节接收图像大小信息
    image_size = int.from_bytes(size_data, byteorder='big')# 将字节转换为整数

    timeNow = str(time.time())
   
    image_path = 'Version 3.0\\serverlog\\{}.png'.format(timeNow)

    time.sleep(0.05)
    # 接收图像数据
    image_data = b''
    while len(image_data) < image_size:
      data = dataSocket.recv(1024)
      if not data:
            break
      image_data += data
   
    # 将图像数据保存为文件
    with open(image_path, 'wb') as file:
      file.write(image_data)
   
    print('图像接收完成')

    """---------------接收完图像后发送给所有人--------------------"""

    print("开始发送")
    for k in user:# 遍历user

      # fs = "C " + info.split(' ', 1)# 聊天内容
      # user.send(fs.encode())# 发送聊天内容

      # Note.write(fs)
      time.sleep(0.05)
      texts = "IMAGE " + info.split(' ', 1) + " " + timeNow
      time.sleep(0.05)
      user.send(texts.encode())

      with open(image_path, 'rb') as file:
            image_data = file.read()
      
      # 发送图像大小信息
      image_size = len(image_data)
      size_data = image_size.to_bytes(4, byteorder='big')# 将整数转换为字节
      user.sendall(size_data)
      
      # 发送图像数据
      user.sendall(image_data)
      time.sleep(1)


      # user.send("gaspatlazidbaafdsfaya".encode())
   
    print("发送完成")

    f = open('Version 3.0\Liaotiainjjilu.txt', 'a', encoding='utf-8')
    f.write("IMAGERECORD " + info.split(' ', 1) + " " + timeNow+ " " + str(time.strftime('%Y-%m-%d %H:%M:%S')))
    f.write('\n')
    f.close()

    print("写入完成")


def userLogin(info, dataSocket):
    """
    录入用户登录业务
    """
    print(info)
    user_text = open(r"Version 3.0\user_text.txt", mode="r", encoding="utf-8")
    lines = user_text.readlines()
    IF_REG = 0
    if len(info.split(' ', 2)) == 1:# 没看懂(
      dataSocket.send("NO".encode())
    elif info.split(' ', 2) in user:# 如果这个用户名已经在user里了
      dataSocket.send("NO".encode())# 拒接注册

    for user_len in range(0, len(lines)):
      # print(lines.split(" ", 1) + " " + lines.split(" ", 1) + '\n')

      if (lines.split(" ", 1) == info.split(' ', 2) and lines.split(" ", 1) == info.split(' ', 2)+'\n'):
            user] = dataSocket    # 添加用户名为键,用户连接为值
            dataSocket.send("OK".encode())# 返回"OK"


            chatRecord(dataSocket)



            IF_REG = 1# 是否注册为1
            for ll in user:
                if (user == user):
                  for key in user.keys():
                        ppp = "R " + key
                        user.send(ppp.encode())
                        # Note.write(ppp)

                        time.sleep(0.3)
    print(user)
    if IF_REG == 0:
      print("NO")
      dataSocket.send("NO".encode())


def UserChar(dataSocket, addr):
    """
    处理用户聊天
    """
    print(info.split(maxsplit=1), end=" ")# 在服务端打印聊天信息

    print(addr, end=" ")# 在服务端打印ip地址
    print(time.strftime('%Y-%m-%d %H:%M:%S'))# 在服务端打印时间   

    for k in user:# 遍历user
      # print(info.split(' ', 1))
      if user != dataSocket:# 发送至所有人(除了自己)
            fs = "C " + info.split(' ', 1)# 聊天内容
            user.send(fs.encode())# 发送聊天内容

            # Note.write(fs)


def Init():
    while True:
      dataSocket, addr = listenSocket.accept()# 获得一个客户端的连接(阻塞式,只有客户端连接后,下面才执行)
      print('接受一个客户端连接:', addr)

      if (1 == 1):
            xd = threading.Thread(target=deal, args=(dataSocket, addr))
            xd.start()# 启动一个线程

def deal(dataSocket, addr):
    global recved, info
   
    try:
      while True:
            
                recved = dataSocket.recv(1024)# 最大接收字节
                info = recved.decode()# 接受的消息
                if len(info) == 0:# 如果接受的消息长度为0
                  # UserExit(dataSocket)
                  # IF_REG = 0# 是否注册为1

                  for key, k in list(user.items()):# 与消息长度为0一样的操作    key:键,k值
                        # print("user k:", k, "user:", user, "dataSocket:", dataSocket)

                        # 处理用户意外断开
                        if k == dataSocket:# user k: <socket.socket fd=188, family=2, type=1, proto=0, laddr=('192.168.0.103', 80), raddr=('119.3.215.140', 50361)> user key: Admin
                            # print(user)
                            del user
                            # print(user)

                            for ka in user:
                              # print("进入循环删除")
                              print(key + "已退出群聊")
                              # user.send((key + "已退出群聊").encode())
                              user.send(("E " + key).encode())
                              IF_REG = 0
                              dataSocket.close()
                              break
                  print(user)      
                  break

                if info.split(' ', 1) == "IMAGE":
                  print("收到请求(图片")
                  imageChat(info, dataSocket)

                elif info.split(' ', 1) == 'R':
                  userLogin(info, dataSocket)
                  
               
                elif info.split(maxsplit=1) == "C":# 如果请求是聊天
                  UserChar(dataSocket, addr)
                  f = open('Version 3.0\Liaotiainjjilu.txt', 'a', encoding='utf-8')
                  f.write("CHATRECORD " + info.split(' ', 1).split(": ", 1) + " " + info.split(' ', 1).split(": ", 1) + " " + time.strftime('%Y-%m-%d %H:%M:%S'))
                  f.write('\n')
                  f.close()
                  # print("写入成功!")
    except Exception as e:
      print('报错:', e)
      for key, k in list(user.items()):# 与消息长度为0一样的操作    key:键,k值
            # print("user k:", k, "user:", user, "dataSocket:", dataSocket)

            # 处理用户意外断开
            if k == dataSocket:# user k: <socket.socket fd=188, family=2, type=1, proto=0, laddr=('192.168.0.103', 80), raddr=('119.3.215.140', 50361)> user key: Admin
                # print(user)
                del user
                # print(user)

                for ka in user:
                  # print("进入循环删除")
                  print(key + "已退出群聊")
                  # user.send((key + "已退出群聊").encode())
                  user.send(("E " + key).encode())
                  IF_REG = 0
                  dataSocket.close()
                  break

            print(user)





if __name__ == "__main__":
    listenSocket = socket(AF_INET, SOCK_STREAM)

    # listenSocket.setsockopt(SOL_SOCKET, SOCK_STREAM, True)
    # listenSocket.ioctl(SIO_KEEPALIVE_VALS, (1, 60 * 1000, 30 * 1000))

    # socket绑定地址和端口
    listenSocket.bind(('0.0.0.0', 1234))
    listenSocket.listen()



    print(f'服务端启动成功,等待客户端连接...')
    Init()
客户端:
"""
作者:Mike_python
时间:2023/2/26
完稿:2023/7/23
文件内容:客户端
"""

from tkinter import *
from ttkbootstrap import *
from tkinter import messagebox as mg
import socket
import threading
import time
import sys
import os
from tkinter.font import Font
from PIL import ImageTk, Image
from tkinter import filedialog

client = socket.socket(socket.AF_INET, socket.SOCK_STREAM)



def centerWindow(root, width, height):
    """
    窗口居中代码
    """
    screenwidth = root.winfo_screenwidth()# 获取显示屏宽度
    screenheight = root.winfo_screenheight()# 获取显示屏高度
    size = '%dx%d+%d+%d' % (width, height, (screenwidth - width) / 2, (screenheight - height) / 2)# 设置窗口居中参数
    root.geometry(size)# 让窗口居中显示



def loginSendToServer(root, passwordWar, usernameWar):
    """验证登录"""
    global client
   
    client.connect(('202.189.5.24', 49405))

    client.send(("R "+usernameWar.get() + " " + passwordWar.get()).encode())   # 发送注册请求


    while True:

      data = client.recv(1024)
      info = data.decode()

      if (info == 'OK'):
            login_root.withdraw()# 隐藏登录窗口
   
            main()
            break

            
      elif (info == 'NO'):
            mg.showerror("","用户名或密码错误!")
            sys.exit(0)


def insert_newline(*args):
    """Control-Return后的换行"""
    send_entry.insert("insert", "\n")
    return "break"

def fasong_Init(*args):
    """fasong的桥梁"""
    fasong()
    # send_entry.delete("0.0", END)   # 设置发送为空
    return 'break'

def fasong(*args):
    re_data = send_entry.get("1.0", END)[:-1]
    if 'exit' == re_data:   # 判断是否退出
      client.send(("Q "+ username).encode())# 发送退出的请求
      client.close()

    elif (re_data != " \n" and re_data != "\n" and re_data != "" and re_data != " "):    # 判断内容不为空
      
      time_ = time.strftime('%Y-%m-%d %H:%M:%S')                  # 以下为自己说的话

      chat_text.config(state=NORMAL)

      #f1 = Font("微软雅黑", 8)
      chat_text.tag_config("tag_3", font=("微软雅黑", 9), foreground="grey")
      chat_text.insert(END, time_, "tag_3")   # 发送时间
      chat_text.insert(END, "\n")

      #f = Font("微软雅黑", 13)
      chat_text.tag_config("tag_41", font=("微软雅黑", 14), foreground="#808080")
      chat_text.insert(END, username + ":", "tag_41")    # 发送文本内容c:\迅雷下载\SimplifiedChinese\SourceHanSansSC-Medium.otf
      chat_text.insert(END, "\n")
      
      #f = Font("微软雅黑", 12)
      chat_text.tag_config("tag_4", font=("微软雅黑", 13), foreground="#2E8B57")
      chat_text.insert(END, re_data, "tag_4")    # 发送文本内容
      chat_text.insert(END, "\n")

      chat_text.update_idletasks()

      chat_text.config(state=DISABLED)
      chat_text.see("end")    # 转到最后一行

      chat_text.update_idletasks()


      # send_entry.first()
      # send_entry.delete(0.1,2.0)      # 设置发送为空
      # send_entry.insert('1 wordstart' , "s")
      # time.sleep(0.1)
      send_entry.delete("0.0", END)   # 设置发送为空

      time.sleep(0.15)
      client.send(("C " + username + ": " + re_data).encode())

def sendImage():
    time.sleep(1)
    image_path = filedialog.askopenfilename()
    if (len(image_path)>=1):

      with open(image_path, 'rb') as file:
            image_data = file.read()
      

      client.send(("IMAGE " + username).encode())

      # 发送图像大小信息
      image_size = len(image_data)
      size_data = image_size.to_bytes(4, byteorder='big')# 将整数转换为字节
      client.sendall(size_data)
      
      # 发送图像数据
      client.sendall(image_data)

      """发送后将图片放到text中"""
      # time_ = time.strftime('%Y-%m-%d %H:%M:%S')                  # 以下为自己说的话

      # chat_text.config(state=NORMAL)

      # #f1 = Font("微软雅黑", 8)
      # chat_text.tag_config("tag_3", font=("微软雅黑", 9), foreground="grey")
      # chat_text.insert(END, time_, "tag_3")   # 发送时间
      # chat_text.insert(END, "\n")

      # #f = Font("微软雅黑", 13)
      # chat_text.tag_config("tag_41", font=("微软雅黑", 14), foreground="#808080")
      # chat_text.insert(END, username + ":", "tag_41")    # 发送文本内容c:\迅雷下载\SimplifiedChinese\SourceHanSansSC-Medium.otf
      # chat_text.insert(END, "\n")
      
      # image = Image.open(image_path)
      # pphoto = ImageTk.PhotoImage(image)
      # chat_text.image_create(END, image=pphoto)#用这个方法创建一个图片对象,并插入到“END”的位置
      # chat_text.insert(END, "\n")
      # chat_text.image = pphoto

      # chat_text.update_idletasks()
      # chat_text.update()

      chat_text.config(state=DISABLED)
      chat_text.see("end")    # 转到最后一行

      # chat_text.update_idletasks()

      
      print('图像发送完成')
      mg.showinfo("", "发送图片完成")
   
def insert_image(canvas, image):
    canvas.create_image(0, 0, anchor="nw", image=image)

ls=[]
for i in range(0, 1000):
    ls.append(str(i))
i=0
def show_image(image_path):
    global i
    image = Image.open(image_path)
    ls = ImageTk.PhotoImage(image)
    chat_text.image_create(END, image=ls)#用这个方法创建一个图片对象,并插入到“END”的位置
    chat_text.tag_configure("{}".format(str(i)), wrap="none")
    chat_text.insert(END, "\n")
    chat_text.image = ls
    i+=1


def jieshou():
    global i
    while True:
      # time.sleep(0.3)
      try:
            try:
                data = client.recv(5000)
                res = data.decode()
            except UnicodeDecodeError:
                # 忽略无法解码的数据
                continue
            if(res != ''):

                # print("1")
                if (res.split(" ", 2)=="C"): # 如果为聊天的请求
                  # print(res.split(" ", 1))
                  # print(res.split(" ", 1))
                  # print(res)
                  time_ = time.strftime('%Y-%m-%d %H:%M:%S')

                  chat_text.config(state=NORMAL)
                  f1 = Font(size=10)
                  chat_text.tag_config("tag_1", font=("微软雅黑", 9), foreground="grey")   
                  chat_text.insert(END, time_, "tag_1")
                  chat_text.insert(END, "\n")

                  f = Font(size=15)
                  chat_text.tag_config("tag", font=("微软雅黑", 14), foreground="#808080")
                  chat_text.insert(END, res.split(" ", 2), "tag")
                  chat_text.insert(END, "\n")
                  
                  f = Font(size=14)
                  chat_text.tag_config("tag_2", font=("微软雅黑", 13), foreground="black")
                  chat_text.insert(END, res.split(" ", 2), "tag_2")
                  chat_text.insert(END, "\n")

                  chat_text.config(state=DISABLED)
                  chat_text.see("end")


                if(res.split(" ", 1)=="R"):    # 在线用户请求
                  afd = False
                  print(res.split(" ", 1))
                  for kk in range(0, online_user.size()): # 循环判断在线列表里是否有用户名
                        if online_user.get(kk) == (res.split(" ", 1)):   # 检测到是
                            afd = True# 判断变量为真
                            break   # 退出
                  if (afd ==False): # 如果判断变量为假
                        online_user.insert(END,res.split(" ", 1))    # 插入用户名


                if(res.split(" ", 1)=="E"):    # 退出请求
                  print("收到退出请求")
                  for kk in range(0, online_user.size()): # 循环判断要删除的用户名
                        if online_user.get(kk) == (res.split(" ", 1)):   
                            online_user.delete(kk)# 从在线列表去除
                            online_user.update()
                            break

                if(res.split(" ", 1) == "IMAGE"):
                  print("开始接收图像")

                  image_path = './log\\image\\{}.png'.format(res.split(" ", 2))
                  

                  size_data = client.recv(4)# 以4个字节接收图像大小信息
                  image_size = int.from_bytes(size_data, byteorder='big')# 将字节转换为整数

                  image_data = b''
                  while len(image_data) < image_size:
                        data = client.recv(1024)
                        if not data:
                            break
                        image_data += data
                  
                  # 将图像数据保存为文件
                  with open(image_path, 'wb') as file:
                        file.write(image_data)


                  time_ = time.strftime('%Y-%m-%d %H:%M:%S')                  # 以下为别人

                  chat_text.config(state=NORMAL)

                  #f1 = Font("微软雅黑", 8)
                  chat_text.tag_config("tag_1", font=("微软雅黑", 9), foreground="grey")   
                  chat_text.insert(END, time_, "tag_1")
                  chat_text.insert(END, "\n")

                  f = Font(size=15)
                  chat_text.tag_config("tag", font=("微软雅黑", 14), foreground="#808080")
                  chat_text.insert(END, res.split(" ", 2), "tag")
                  chat_text.insert(END, "\n")
                  

                  
                  # image = Image.open(image_path)
                  # pphoto = ImageTk.PhotoImage(image)
                  # chat_text.image_create(END, image=pphoto)#用这个方法创建一个图片对象,并插入到“END”的位置
                  # chat_text.insert(END, "\n")
                  # chat_text.image = pphoto

                  show_image(image_path)

                  chat_text.update_idletasks()
                  chat_text.update()

                  chat_text.config(state=DISABLED)
                  chat_text.see("end")    # 转到最后一行
                  
                  print('图像接收完成')
                        


      # else:
      #   continue
      except Exception as e:
            print("ERROR!:", e)

            #break

def receiveFile():
    """接收聊天记录"""
    try:
      time.sleep(0.1)
      print("开始接收聊天记录")
      with open("./log\\聊天记录({}).txt".format(username), 'wb') as file:
            while True:
                # 从客户端接收数据
               

                data = client.recv(30000)
                info = data.decode()

                file.write(data)# 将接收到的数据写入文件

                if ('gaspatlazidbaafdsfaya' in info):
                  print("exit")
                  file.close()
                  break
    except:
      mg.showerror("", "聊天记录读取失败(图片)")



def putChatToText():
    """将读取到的历史消息放置到聊天界面上"""

    user_text = open("./log\\聊天记录({}).txt".format(username), mode="r", encoding="utf-8")
    lines = user_text.readlines()
    for user_len in range(0, len(lines)-1):
      try:
            if (lines.split(" ", 3) == "CHATRECORD"):
                chat_text.config(state=NORMAL)

                f1 = Font(size=10)
                chat_text.tag_config("tag_1", font=("微软雅黑", 9), foreground="grey")   
                chat_text.insert(END, lines.split(" ", 3), "tag_1")
                # chat_text.insert(END, "\n")

                f = Font(size=15)
                chat_text.tag_config("tag", font=("微软雅黑", 14), foreground="#808080")
                chat_text.insert(END, lines.split(" ", 3), "tag")
                chat_text.insert(END, "\n")
               
                f = Font(size=14)
                chat_text.tag_config("tag_2", font=("微软雅黑", 13))
                chat_text.insert(END,lines.split(" ", 3), "tag_2")
                chat_text.insert(END, "\n")

                chat_text.config(state=DISABLED)
                chat_text.see("end")

               
            elif (lines.split(" ", 3) == "IMAGERECORD"):
                chat_text.config(state=NORMAL)

                f1 = Font(size=10)
                chat_text.tag_config("tag_1", font=("微软雅黑", 9), foreground="grey")   
                chat_text.insert(END, lines.split(" ", 3), "tag_1")
                # chat_text.insert(END, "\n")

                f = Font(size=15)
                chat_text.tag_config("tag", font=("微软雅黑", 14), foreground="#808080")
                chat_text.insert(END, lines.split(" ", 2), "tag")
                chat_text.insert(END, "\n")
               
                # image = Image.open('Version 3.0\\log\\image\\{}.png'.format(lines.split(" ", 3)))
                # pphoto = ImageTk.PhotoImage(image)
                # chat_text.image_create(END, image=pphoto)#用这个方法创建一个图片对象,并插入到“END”的位置
                # chat_text.insert(END, "\n")
                # chat_text.image = pphoto

                show_image('./log\\image\\{}.png'.format(lines.split(" ", 3)))

                chat_text.config(state=DISABLED)
                chat_text.see("end")
      except:
            chat_text.config(state=NORMAL)
            chat_text.tag_config("tag_31", font=("微软雅黑", 14), foreground="red")
            chat_text.insert(END, "历史消息放置失败", "tag_31")
            chat_text.insert(END, "\n")

            chat_text.config(state=DISABLED)
            chat_text.see("end")


    chat_text.config(state=NORMAL)
    chat_text.tag_config("tag_31", font=("微软雅黑", 14), foreground="blue")
    chat_text.insert(END, "-----------------------以上为历史消息-----------------------", "tag_31")
    chat_text.insert(END, "\n")

    chat_text.config(state=DISABLED)
    chat_text.see("end")


      
def SystemSetting():
    setting_root = Toplevel(login_root)
    setting_root.title("设置")
    centerWindow(setting_root, 400, 200)



def main():
    """登录后主界面"""

    global chat_text, send_entry, online_user, username
   
    # root = login_root.Toplevel(themename="morph")
    username = usernameWar.get()

    try:
      receiveFile()
    except:
      mg.showerror("", "聊天记录读取错误!")

   

    root = Toplevel(login_root)
    root.title("聊天界面")
    centerWindow(root, 900, 600)

    def exit_():
      root.destroy()
      os._exit(0)


            
            
   

    new_thread = threading.Thread(target=jieshou, name="T1")   
    # 启动新线程
    new_thread.start()

    new_thread1 = threading.Thread(target=fasong, name="T2")
    # 启动新线程
    new_thread1.start()


    """------------------------------------------------frame左(聊天区域)------------------------------------------------左侧frame"""


    centerFrame = Frame(root, width=650, height=560)
    centerFrame.place(x=20, y=20)

    """------------------------------文本接收-------------------------------------------"""
    text_frame = Frame(centerFrame)
    text_frame.place(x = 10, y = 10)
    gun_song_tiao_y = Scrollbar(text_frame, bootstyle="secondary-round")
    gun_song_tiao_x = Scrollbar(text_frame, orient=HORIZONTAL, bootstyle="secondary-round")

    chat_text = Text(text_frame, height=21, width=67, wrap='none', relief=GROOVE, font=('微软雅黑', 11))#, state=DISABLED

    gun_song_tiao_y.pack(side=RIGHT,fill=Y)
    gun_song_tiao_x.pack(side=BOTTOM, fill=X)

    chat_text.pack()

    gun_song_tiao_y.config(command=chat_text.yview)
    gun_song_tiao_x.config(command=chat_text.xview)
                           
    chat_text.config(yscrollcommand=gun_song_tiao_y.set)
    chat_text.config(xscrollcommand=gun_song_tiao_x.set)
    """------------------------------文本接收-------------------------------------------"""



    """------------------------------发送框-------------------------------------------"""
    send_entry = Text(centerFrame, width=55, height=4, font=("微软雅黑", 13)) # 发送区域
    send_entry.place(x=10, y=460)


    send_button = Button(centerFrame, text="\n发 送\n", command=fasong_Init)   # 发送按钮
    send_button.place(x=585, y=460)

    phtotICON = Image.open(r"./log\图片1_pic-one.png")
    photowidth, photoheight = phtotICON.size
    photonew_width = int(photowidth * 0.06)# 调整宽度为原始宽度的50%
    photonew_height = int(photoheight * 0.06)# 调整高度为原始高度的50%
    photoimage = phtotICON.resize((photonew_width, photonew_height))# 调整图像大小
    photo = ImageTk.PhotoImage(photoimage)

    image_button = Button(centerFrame, image=photo, bootstyle="info-outline", command=sendImage)
    image_button.place(x=575, y=530)

    phtotICON1 = Image.open(r"./log\设置_setting-three.png")
    photowidth1, photoheight1 = phtotICON1.size
    photonew_width1 = int(photowidth1 * 0.06)# 调整宽度为原始宽度的50%
    photonew_height1 = int(photoheight1 * 0.06)# 调整高度为原始高度的50%
    photoimage1 = phtotICON1.resize((photonew_width1, photonew_height1))# 调整图像大小
    photo1 = ImageTk.PhotoImage(photoimage1)

    settingButton = Button(centerFrame, image=photo1, bootstyle="info-outline", command=SystemSetting)
    settingButton.place(x=613, y=530)


    send_entry.bind("<Return>", fasong_Init)
    send_entry.bind("<Control-Return>", insert_newline)
    """------------------------------发送框-------------------------------------------"""


    """------------------------------------------------右侧frame(在线列表)------------------------------------------------左侧frame"""
    RightFrame = Frame(root, width=200, height=560)
    RightFrame.place(x=680, y=20)

    online_user = Listbox(RightFrame, height=30, width=35)
    online_user.place(x=5, y=5)
    online_user.config(font=("微软雅黑", 14))


    putChatToText()


    root.protocol("WM_DELETE_WINDOW", exit_)
    root.mainloop()

def reg_():
    """注册"""
    mg.showinfo("", "请前往鱼c论坛注册")




def login():
    """登录界面"""
    # global passwordWar, usernameWar, root

    def bind_return_key(event=None):
      """回车后进行登录验证"""
      loginSendToServer(login_root, passwordWar, usernameWar)

    def SetFocusToPassword(*args):
      """将焦点设置到PasswordEntry"""
      passwordEntry.focus_set()



    global login_root, usernameWar
    global username


    login_root = Window(themename="morph")
    login_root.title("登录界面")
    centerWindow(login_root, 500, 600)


    passwordWar = StringVar()
    usernameWar = StringVar()

   

    # 用户名部分
    Label(login_root, text='用户名:', font=("微软雅黑", 14)).place(x=40, y=80)
    usernameEntry = Entry(login_root, font=('微软雅黑', 13), width=22, bootstyle="dark", textvariable=usernameWar)
    usernameEntry.place(x=140, y=80)

    usernameEntry.focus_set() # 使焦点一开始就在输入用户名上


    # 密码部分
    Label(login_root, text='密   码:', font=("微软雅黑", 14)).place(x=40, y=160)
    passwordEntry = Entry(login_root, font=('微软雅黑', 13), width=22, show='*', bootstyle="dark", textvariable=passwordWar)
    passwordEntry.place(x=140, y=160)


    # 登录按钮
    loginButton = Button(login_root, text="登录", bootstyle="info-outline", width=8, command=lambda: loginSendToServer(login_root, passwordWar, usernameWar))
    loginButton.place(x=200, y=300)
    # 注册按钮
    regButton = Button(login_root, text="没有账号?点我注册", bootstyle="info-link", width=20, command=reg_).place(x=150, y=360)

   
    usernameEntry.bind("<Return>", SetFocusToPassword) # 绑定回车到输入密码
    passwordEntry.bind("<Return>", bind_return_key) # 绑定回车进行登录

    login_root.mainloop()


if __name__ == "__main__":

    login()





Mikepython0721 发表于 2023-8-13 14:57

mainblog 发表于 2023-8-13 14:55
没搞懂这个怎么跑,注册也是提示去C

哈哈,程序都给你了就不要注意注册了,把客户端的链接ip换成127.0.0.1:1234,然后创建一个user_text.txt

按照

用户名 密码

这个格式填写就行了,之后运行就行

Mikepython0721 发表于 2023-8-13 17:17

本帖最后由 Mikepython0721 于 2023-8-13 17:50 编辑

burning 发表于 2023-8-13 17:13
一运行一堆文件图片找不到,这些附加资源可以提供吗


这里面只有客户端和素材,没有服务端

sai609 发表于 2023-8-13 12:51

python聊天室。。。干嘛用的

Mikepython0721 发表于 2023-8-13 10:05

注:我在另一个论坛上发表过同样内容,本人完全原创

L__ 发表于 2023-8-13 10:14

果然优秀的人才多

sina0022 发表于 2023-8-13 10:25

受教了,复制下来,学习一下,感谢分享

L1ghtXW 发表于 2023-8-13 10:40

厉害,等我细心学习一下,才刚刚起步python:)

LQ584521 发表于 2023-8-13 10:47

学习下。感谢楼主。

52bojie 发表于 2023-8-13 10:48

非常棒,学习一下。谢谢分享

w759003376 发表于 2023-8-13 10:50

感谢楼主,学一波

86618513 发表于 2023-8-13 10:54

wan456 发表于 2023-8-13 11:00

Version 3.0\Liaotiainjjilu.txt
能存多少数据
页: [1] 2 3 4 5 6 7 8
查看完整版本: python聊天室3.0