只写了登录聊天

This commit is contained in:
lsy2246 2024-04-23 22:05:31 +08:00
parent 4e1b559648
commit 8e6adb5259
28 changed files with 1052 additions and 60 deletions

View File

@ -0,0 +1,9 @@
import wx
class voice_frame(wx.Frame):
def __init__(self,Id):
super().__init__()
panel = wx.Panel(self)
box = wx.BoxSizer(wx.VERTICAL)

View File

@ -4,11 +4,10 @@ import wx
import time
import multiprocessing
from Client.Transmission.Process_Client import ProcessClient
class ChatFrame(wx.Frame,ProcessClient):
class ChatFrame(wx.Frame, ProcessClient):
def __init__(self, Id):
wx.Frame.__init__(self, None, size=(800, 600), title="账号: " + str(Id))
ProcessClient.__init__(self)
@ -91,11 +90,6 @@ class ChatFrame(wx.Frame,ProcessClient):
ChatMain_Panel.SetSizer(ChatMain_box)
self.root_path = rf'.\{Id}'
self.Account_path = self.root_path + r'\Account.csv'
self.Contacts_path = self.root_path + r'\Contacts.csv'
self.History_path = self.root_path + r'\History.csv'
def click_chat_button(self, event):
self.chat_page.Hide()
self.connect_page.Hide()
@ -120,19 +114,6 @@ class ChatFrame(wx.Frame,ProcessClient):
self.site_page.Show()
self.Layout()
def send_Chat_history(self, Contact, send, receive, Type, data, UpDataTime):
chat_panel = self.chat_page.chat_page_map[Contact]
if Type == 'text':
contents = ['My' if Contact == send else 'Ta']
contents.append('') # 添加一个空字符串作为消息的一部分
for i in range(0, len(data), 30):
contents.append(data[i:i + 30])
contents.append(UpDataTime)
for content in contents:
chat_panel.chat_receive_text.AppendText(content+'\n')
def click_find_button(self, event):
self.chat_page.Hide()
self.connect_page.Hide()
@ -149,20 +130,22 @@ class ChatFrame(wx.Frame,ProcessClient):
Contact = data['Contact']
Remark = data['Remark']
Time = data['UpDataTime']
state = data['state']
if state:
wx.CallAfter(self.chat_page.ChatPage_add_Contact_person, Contact, Remark)
case 'ChatPage_add_Contact_tab':
case 'Chat_screen_show':
Contact = None
data = data['content']
send = data['send']
receive = data['receive']
send = data['Send']
receive = data['Receive']
Type = data['Type']
content = data['content']
UpDataTime = data['UpDataTime']
content = data['Content']
UpDataTime = data['Time']
if send == str(self.userid):
Contact = receive
elif receive == str(self.userid):
Contact = send
wx.CallAfter(self.send_Chat_history, Contact, send, receive, Type, content, UpDataTime)
wx.CallAfter(self.chat_page.Chat_screen_show, Contact, send, receive, Type, content, UpDataTime)
class ChatPage(wx.Panel):
def __init__(self, parent):
@ -182,7 +165,7 @@ class ChatFrame(wx.Frame,ProcessClient):
def ChatPage_add_Contact_person(self, Id, Remark):
contact_page = wx.Panel(self.ChatPage_Listbook)
self.ChatPage_Listbook.AddPage(contact_page, Remark)
chat_page = self.ChatPage_add_Contact_tab()
chat_page = self.ChatPage_add_Contact_tab(Id)
self.chat_page_map[Id] = chat_page
self.chat_page_ids.append(Id)
@ -199,12 +182,15 @@ class ChatFrame(wx.Frame,ProcessClient):
# 重新布局
self.Layout()
def ChatPage_add_Contact_tab(self):
def ChatPage_add_Contact_tab(self, Id):
chat_panel = wx.Panel(self)
chat_box = wx.BoxSizer(wx.VERTICAL)
chat_panel.contact_id = Id
chat_receive_box = wx.BoxSizer(wx.HORIZONTAL)
chat_panel.chat_receive_text = rt.RichTextCtrl(chat_panel, style=wx.TE_MULTILINE | wx.TE_READONLY)
chat_panel.chat_receive_text = rt.RichTextCtrl(chat_panel,
style=wx.VSCROLL | wx.HSCROLL | wx.NO_BORDER | wx.WANTS_CHARS)
chat_receive_box.Add(chat_panel.chat_receive_text, 1, wx.EXPAND, 0)
chat_box.Add(chat_receive_box, 2, wx.EXPAND, 0)
@ -224,12 +210,60 @@ class ChatFrame(wx.Frame,ProcessClient):
chat_box.Add(chat_send_box, 1, wx.EXPAND, 0)
send_button = wx.Button(chat_panel, label='发送') # Create a send button
send_button.Bind(wx.EVT_BUTTON, self.on_send_button_click)
chat_send_box.Add(send_button, 0, wx.EXPAND | wx.LEFT, 5) # Add the button to the send box
chat_panel.SetSizer(chat_box)
return chat_panel
def Chat_screen_show(self, Contact, send, receive, Type, data, UpDataTime):
chat_panel = self.chat_page_map[Contact]
if Type == 'text':
# 确定对齐方式
if Contact == receive:
alignment = wx.TEXT_ALIGNMENT_RIGHT
else:
alignment = wx.TEXT_ALIGNMENT_LEFT
# 开始设置对齐
chat_panel.chat_receive_text.BeginAlignment(alignment)
# 按每30个字符分割消息内容并写入
contents = [data[i:i + 30] for i in range(0, len(data), 30)]
contents.append(UpDataTime) # 添加时间戳
for content in contents:
chat_panel.chat_receive_text.WriteText(content + '\n') # WriteText处理换行
# 结束对齐设置
chat_panel.chat_receive_text.EndAlignment()
# 添加额外的新行(如果需要)
chat_panel.chat_receive_text.Newline()
# 在添加完所有消息后
chat_panel.chat_receive_text.ShowPosition(chat_panel.chat_receive_text.GetLastPosition())
chat_panel.Refresh()
chat_panel.Update()
self.Layout()
def on_send_button_click(self, event):
button = event.GetEventObject()
chat_panel = button.GetParent()
send_text = chat_panel.chat_send_text.GetValue() # 正确获取输入框内容
contact_id = str(chat_panel.contact_id) # 获取联系人ID
if send_text == '':
return
self.Chat_screen_show(contact_id, None, contact_id, 'text', send_text,
time.strftime('%Y-%m-%d %H:%M:%S', time.localtime()))
data = {"Type": "text", "content": send_text}
content = {"genre": '聊天记录', "target": contact_id, "content": data}
top_frame = self.GetTopLevelParent()
top_frame.Process_client_send('Session_server', 'send_server', content)
chat_panel.chat_send_text.SetValue('') # 清空输入框
event.Skip()
def on_page_changed(self, event):
# 获取当前选定的页面的索引
current_page_index = self.ChatPage_Listbook.GetSelection()

View File

@ -0,0 +1,270 @@
import json
import multiprocessing
import os
import wx
import threading
import time
from Client.Transmission.Process_Client import ProcessClient
from .Chat_main import ChatFrame
def open_chat_window(Id):
app = wx.App()
ChatFrame(Id).Show()
app.MainLoop()
class LoginFrame(wx.Frame, ProcessClient):
def __init__(self):
wx.Frame.__init__(self, None, id=-1, title='登录', pos=wx.DefaultPosition, size=(380, 300))
ProcessClient.__init__(self)
current_file_path = __file__
current_file_name = os.path.basename(current_file_path).split('.')[0]
self.Process_client_send("Server", "Name", current_file_name)
# 创建菜单栏
menu_bar = wx.MenuBar()
# 登录菜单
login_menu = wx.Menu()
menu_bar.Append(login_menu, "登录")
# 更多菜单
more_menu = wx.Menu()
self.register_id = wx.NewId()
self.set_server_id = wx.NewId()
more_menu.Append(self.register_id, "注册账号")
more_menu.Append(self.set_server_id, "服务器设置")
menu_bar.Append(more_menu, "更多")
self.SetMenuBar(menu_bar)
# 创建状态栏
self.status_bar = self.CreateStatusBar(2)
self.server_status = False # 服务器状态
status_thread = threading.Thread(target=self.update_status_bar(None), daemon=True)
status_thread.start()
# 启动定时器,每秒钟触发一次
self.timer = wx.Timer(self)
self.Bind(wx.EVT_TIMER, self.update_status_bar, self.timer)
self.timer.Start(1000) # 设置定时器间隔为1000毫秒1秒
# 获取菜单点击事件
self.Bind(wx.EVT_MENU, self.click_menu, id=self.register_id)
self.Bind(wx.EVT_MENU, self.click_menu, id=self.set_server_id)
self.Bind(wx.EVT_MENU_OPEN, self.click_menu_title)
# 创建注册面板
self.sizer = wx.BoxSizer(wx.VERTICAL)
self.login_panel = LoginPanel(self)
self.register_panel = RegisterPanel(self)
self.sizer.Add(self.login_panel, 1, wx.EXPAND)
self.sizer.Add(self.register_panel, 1, wx.EXPAND)
self.login_panel.Hide()
self.register_panel.Hide()
self.login_panel.Show()
# 主页按钮绑定
self.Bind(wx.EVT_BUTTON, self.send_login_button, self.login_panel.LoginPanel_login_label)
self.Bind(wx.EVT_BUTTON, self.send_register_button, self.register_panel.RegisterPanel_login_label)
self.SetSizer(self.sizer)
def update_status_bar(self, event):
if self.server_status:
self.status_bar.SetStatusText("服务器\t已连接", 0)
else:
self.status_bar.SetStatusText("服务器\t未连接", 0)
self.status_bar.SetStatusText("时间\t" + time.strftime('%Y-%m-%d %H:%M:%S', time.localtime()), 1)
def click_menu_title(self, event):
menu = event.GetMenu()
menu_title = menu.GetTitle()
if menu_title == "登录":
self.login_panel.Hide()
self.register_panel.Hide()
self.login_panel.Show()
self.Layout()
# 点击菜单检测
def click_menu(self, event):
menu_id = event.GetId()
if menu_id == self.register_id:
self.login_panel.Hide()
self.register_panel.Hide()
self.register_panel.Show()
self.Layout()
elif menu_id == self.set_server_id:
self.login_panel.Hide()
self.register_panel.Hide()
self.Layout()
def login_page_receive(self, receive_content):
if receive_content["genre"] == '登录':
match receive_content["data"]['status']:
case 0:
self.Process_client_send("File_operate", "detection_data", receive_content["data"]['account'])
wx.MessageBox('登录成功正在获取数据', '登录', wx.OK | wx.ICON_INFORMATION)
case -1:
wx.MessageBox('重复登录', '登录', wx.OK | wx.ICON_INFORMATION)
case 1:
wx.MessageBox('密码错误', '登录', wx.OK | wx.ICON_INFORMATION)
case 2:
wx.MessageBox('未找到该账号', '登录', wx.OK | wx.ICON_INFORMATION)
elif receive_content["genre"] == '注册':
wx.MessageBox(
f'注册成功\n网名 : {receive_content["data"]['NetName']} \n账号 : {receive_content["data"]['Id']} \n密码 : {receive_content["data"]['Password']}',
'注册', wx.OK | wx.ICON_INFORMATION)
def send_login_button(self, event):
if self.server_status:
account = self.login_panel.LoginPanel_account_text.GetValue().strip()
password = self.login_panel.LoginPanel_password_text.GetValue().strip()
content = {'account': account, 'password': password}
target = "服务器"
genre = "登录"
data = {"genre": genre, "target": target, "content": content}
if account and password:
self.Process_client_send("Session_server", "send_server", data)
def send_register_button(self, event):
if self.server_status:
account = self.register_panel.RegisterPanel_account_text.GetValue().strip()
password = self.register_panel.RegisterPanel_password_text.GetValue().strip()
content = {'account': account, 'password': password}
target = "服务器"
genre = "注册"
data = {"genre": genre, "target": target, "content": content}
if account and password:
self.Process_client_send("Session_server", "send_server", data)
def Process_client_pick(self, data):
if data['target'] in ['ALL', 'Login']:
match data['function']:
case 'server_status':
self.server_status = data['content']
case 'login_page_receive':
self.login_page_receive(data['content'])
case '更新完成':
multiprocessing.Process(target=open_chat_window, args=(data['content'],)).start()
self.Destroy()
class LoginPanel(wx.Panel):
def __init__(self, parent):
super().__init__(parent)
# 主盒子
LoginPanel_main_box = wx.BoxSizer(wx.VERTICAL)
# 顶部盒子,目前只放了软件名
LoginPanel_top_box = wx.BoxSizer(wx.VERTICAL) # 使用垂直盒子
LoginPanel_show_title = wx.StaticText(self, label='登录')
LoginPanel_show_title.SetFont(wx.Font(30, wx.FONTFAMILY_DEFAULT, wx.FONTSTYLE_NORMAL, wx.FONTWEIGHT_NORMAL))
LoginPanel_top_box.Add(LoginPanel_show_title, 1, wx.ALIGN_CENTER_HORIZONTAL | wx.ALL, 10)
LoginPanel_main_box.Add(LoginPanel_top_box, 0, wx.EXPAND)
# 中部盒子,放账号和密码
LoginPanel_content_box = wx.BoxSizer(wx.VERTICAL)
# 账号
LoginPanel_account_box = wx.BoxSizer(wx.HORIZONTAL)
LoginPanel_account_label = wx.StaticText(self, label=' 账号:')
LoginPanel_account_label.SetFont(
wx.Font(15, wx.FONTFAMILY_DEFAULT, wx.FONTSTYLE_NORMAL, wx.FONTWEIGHT_NORMAL))
LoginPanel_account_box.Add(LoginPanel_account_label, 0, wx.ALIGN_CENTER_VERTICAL)
self.LoginPanel_account_text = wx.TextCtrl(self, size=(300, 30))
self.LoginPanel_account_text.SetHint('请输入账号')
LoginPanel_account_box.Add(self.LoginPanel_account_text, 1, wx.ALIGN_CENTER_VERTICAL)
LoginPanel_content_box.Add(LoginPanel_account_box)
# 添加空白控件来增加间距
LoginPanel_content_box.Add(wx.StaticText(self, label=''), 0, wx.ALL, 5)
# 密码
LoginPanel_password_box = wx.BoxSizer(wx.HORIZONTAL)
LoginPanel_password_label = wx.StaticText(self, label=' 密码:')
LoginPanel_password_label.SetFont(
wx.Font(15, wx.FONTFAMILY_DEFAULT, wx.FONTSTYLE_NORMAL, wx.FONTWEIGHT_NORMAL))
LoginPanel_password_box.Add(LoginPanel_password_label, 0, wx.ALIGN_CENTER_VERTICAL)
self.LoginPanel_password_text = wx.TextCtrl(self, size=(300, 30))
self.LoginPanel_password_text.SetHint('请输入密码')
LoginPanel_password_box.Add(self.LoginPanel_password_text, 1, wx.ALIGN_CENTER_VERTICAL)
LoginPanel_content_box.Add(LoginPanel_password_box)
LoginPanel_main_box.Add(LoginPanel_content_box, 0, wx.EXPAND)
# 底部盒子
LoginPanel_bottom_box = wx.BoxSizer(wx.VERTICAL)
# 登录按钮
LoginPanel_login_box = wx.BoxSizer(wx.VERTICAL) # 使用垂直盒子布局
self.LoginPanel_login_label = wx.Button(self, size=(200, 50), label='登录')
LoginPanel_login_box.AddStretchSpacer() # 添加一个可伸缩的空间,将登录按钮推到垂直中间
LoginPanel_login_box.Add(self.LoginPanel_login_label, 0, wx.ALIGN_CENTER_HORIZONTAL) # 将登录按钮添加到垂直盒子中
LoginPanel_login_box.AddStretchSpacer() # 再次添加一个可伸缩的空间,将登录按钮推到垂直中间
LoginPanel_bottom_box.Add(LoginPanel_login_box, 1,
wx.ALIGN_CENTER_VERTICAL | wx.ALIGN_CENTER_HORIZONTAL) # 将垂直盒子添加到底部盒子中,设置垂直和水平居中对齐
LoginPanel_main_box.Add(LoginPanel_bottom_box, 1, wx.EXPAND) # 将底部盒子添加到主盒子中,使其填满剩余空间
self.SetSizer(LoginPanel_main_box)
class RegisterPanel(wx.Panel):
def __init__(self, parent):
super().__init__(parent)
# 主盒子
RegisterPanel_main_box = wx.BoxSizer(wx.VERTICAL)
# 顶部盒子,目前只放了软件名
RegisterPanel_top_box = wx.BoxSizer(wx.VERTICAL) # 使用垂直盒子
RegisterPanel_show_title = wx.StaticText(self, label='注册')
RegisterPanel_show_title.SetFont(
wx.Font(30, wx.FONTFAMILY_DEFAULT, wx.FONTSTYLE_NORMAL, wx.FONTWEIGHT_NORMAL))
RegisterPanel_top_box.Add(RegisterPanel_show_title, 1, wx.ALIGN_CENTER_HORIZONTAL | wx.ALL, 10)
RegisterPanel_main_box.Add(RegisterPanel_top_box, 0, wx.EXPAND)
# 中部盒子,放账号和密码
RegisterPanel_content_box = wx.BoxSizer(wx.VERTICAL)
# 账号
RegisterPanel_account_box = wx.BoxSizer(wx.HORIZONTAL)
RegisterPanel_account_label = wx.StaticText(self, label=' 用户名:')
RegisterPanel_account_label.SetFont(
wx.Font(15, wx.FONTFAMILY_DEFAULT, wx.FONTSTYLE_NORMAL, wx.FONTWEIGHT_NORMAL))
RegisterPanel_account_box.Add(RegisterPanel_account_label, 0, wx.ALIGN_CENTER_VERTICAL)
self.RegisterPanel_account_text = wx.TextCtrl(self, size=(300, 30))
self.RegisterPanel_account_text.SetHint('请输入用户名')
RegisterPanel_account_box.Add(self.RegisterPanel_account_text, 1, wx.ALIGN_CENTER_VERTICAL)
RegisterPanel_content_box.Add(RegisterPanel_account_box)
# 添加空白控件来增加间距
RegisterPanel_content_box.Add(wx.StaticText(self, label=''), 0, wx.ALL, 5)
# 密码
RegisterPanel_password_box = wx.BoxSizer(wx.HORIZONTAL)
RegisterPanel_password_label = wx.StaticText(self, label=' 密码: ')
RegisterPanel_password_label.SetFont(
wx.Font(15, wx.FONTFAMILY_DEFAULT, wx.FONTSTYLE_NORMAL, wx.FONTWEIGHT_NORMAL))
RegisterPanel_password_box.Add(RegisterPanel_password_label, 0, wx.ALIGN_CENTER_VERTICAL)
self.RegisterPanel_password_text = wx.TextCtrl(self, size=(300, 30))
self.RegisterPanel_password_text.SetHint('请输入密码')
RegisterPanel_password_box.Add(self.RegisterPanel_password_text, 1, wx.ALIGN_CENTER_VERTICAL)
RegisterPanel_content_box.Add(RegisterPanel_password_box)
RegisterPanel_main_box.Add(RegisterPanel_content_box, 0, wx.EXPAND)
# 底部盒子
RegisterPanel_bottom_box = wx.BoxSizer(wx.VERTICAL)
# 登录按钮
RegisterPanel_register_box = wx.BoxSizer(wx.VERTICAL) # 使用垂直盒子布局
self.RegisterPanel_login_label = wx.Button(self, size=(200, 50), label='确认')
RegisterPanel_register_box.AddStretchSpacer() # 添加一个可伸缩的空间,将登录按钮推到垂直中间
RegisterPanel_register_box.Add(self.RegisterPanel_login_label, 0,
wx.ALIGN_CENTER_HORIZONTAL) # 将登录按钮添加到垂直盒子中
RegisterPanel_register_box.AddStretchSpacer() # 再次添加一个可伸缩的空间,将登录按钮推到垂直中间
RegisterPanel_bottom_box.Add(RegisterPanel_register_box, 1,
wx.ALIGN_CENTER_VERTICAL | wx.ALIGN_CENTER_HORIZONTAL) # 将垂直盒子添加到底部盒子中,设置垂直和水平居中对齐
RegisterPanel_main_box.Add(RegisterPanel_bottom_box, 1, wx.EXPAND) # 将底部盒子添加到主盒子中,使其填满剩余空间
self.SetSizer(RegisterPanel_main_box)

View File

@ -0,0 +1,2 @@
from .Chat_main import *
from .Login import *

View File

@ -0,0 +1,103 @@
import os
import csv
import time
from .Process_Client import ProcessClient
class FileOperate(ProcessClient):
def __init__(self, user_id):
ProcessClient.__init__(self)
self.user_id = user_id
self.root_path = None
self.Account_path = None
self.Contacts_path = None
self.History_path = None
self.file_root_path = None
self.other_file_path = None
self.image_file_path = None
current_file_path = __file__
current_file_name = os.path.basename(current_file_path).split('.')[0]
self.Process_client_send("Server", "Name", current_file_name)
def detection_data(self, Id):
self.user_id = Id
self.root_path = rf'.\{Id}'
self.Account_path = self.root_path + r'\Account.csv'
self.Contacts_path = self.root_path + r'\Contacts.csv'
self.History_path = self.root_path + r'\History.csv'
self.file_root_path = self.root_path + r'\file'
self.other_file_path = self.file_root_path + r'\other'
self.image_file_path = self.file_root_path + r'\image'
if not os.path.isdir(self.root_path):
os.mkdir(self.root_path)
if not os.path.isdir(self.file_root_path):
os.mkdir(self.file_root_path)
os.mkdir(self.other_file_path)
os.mkdir(self.image_file_path)
if not os.path.exists(self.Account_path):
with open(self.Account_path, 'w', encoding='utf-8') as f:
pass
with open(self.Account_path, 'r+', encoding='utf-8') as info:
data = csv.DictReader(info)
if os.path.getsize(self.Account_path) == 0: # 检查文件大小是否为0
date = time.strftime('%Y-%m-%d %H:%M:%S', time.localtime(0))
else:
for d in data:
date = d['UpDataTime']
target = "服务器"
genre = "数据更新"
data = {"genre": genre, "target": target, "content": date}
self.Process_client_send("Session_server", "send_server", data)
def read_data(self):
with open(self.Contacts_path, 'r', encoding='utf-8') as Contacts:
data = csv.reader(Contacts)
next(data)
for i in data:
content = {'Contact': i[0], 'Remark': i[1], 'state': i[2], 'UpDataTime': i[3]}
self.Process_client_send("Chat_main", "ChatPage_add_Contact_person", content)
with open(self.History_path, 'r', encoding='utf-8') as History_path:
data = csv.reader(History_path)
next(data)
for i in data:
content = {'Send': i[0], 'Receive': i[1], 'Type': i[2], 'Content': i[3], 'Time': i[4]}
self.Process_client_send("Chat_main", "Chat_screen_show", content)
def save_data(self, data):
target = list(data.keys())[0]
data = list(data.values())[0]
match target:
case 'Account':
with open(self.Account_path, 'w+', encoding='utf-8', newline='') as file:
csv_file = csv.writer(file)
csv_file.writerow(list(data.keys()))
csv_file.writerow(list(data.values()))
case 'Contacts':
with open(self.Contacts_path, 'a+', encoding='utf-8', newline='') as file:
csv_file = csv.writer(file)
if os.path.getsize(self.Contacts_path) == 0: # 检查文件大小是否为0
csv_file.writerow(list(data.keys()))
csv_file.writerow(list(data.values()))
case 'History':
with open(self.History_path, 'a+', encoding='utf-8', newline='') as file:
csv_file = csv.writer(file)
if os.path.getsize(self.History_path) == 0: # 检查文件大小是否为0
csv_file.writerow(list(data.keys()))
csv_file.writerow(list(data.values()))
case '更新完成':
self.Process_client_send("ALL", "更新完成", eval(data))
def Process_client_pick(self, data):
if data['target'] in ['ALL', 'File_operate']:
match data['function']:
case 'detection_data':
self.detection_data(data['content'])
case 'save_data':
self.save_data(data['content'])
case 'read_data':
self.read_data()

View File

@ -0,0 +1,31 @@
import json
import threading
from multiprocessing.connection import Client
class ProcessClient:
def __init__(self):
self.Process_port = 8727
self.Process_server = 'localhost'
self.Process_client_Client = Client((self.Process_server, self.Process_port))
Process_client_recv = threading.Thread(target=self.Process_client_recv)
Process_client_recv.start()
def Process_client_send(self, target, function, content):
data = {"target": target, "function": function, "content": content}
data_json = json.dumps(data)
self.Process_client_Client.send(data_json)
def Process_client_recv(self):
while True:
try:
data_json = self.Process_client_Client.recv()
data = json.loads(data_json)
self.Process_client_pick(data)
except ConnectionResetError as e:
print("连接已关闭: " + str(e))
break
def Process_client_pick(self, data):
pass

View File

@ -0,0 +1,52 @@
import json
import multiprocessing
from multiprocessing.connection import Listener
import threading
class ProcessServer:
def __init__(self):
try:
self.Process_port = 8727
self.Process_server = 'localhost'
self.Process_server_listener = Listener((self.Process_server, self.Process_port))
self.Process_client_link_dick = {}
Process_client_link_Thread = threading.Thread(target=self.Process_client_link)
Process_client_link_Thread.start()
except:
print("进程通信端口绑定失败")
def Process_client_link(self):
while True:
client_connect = self.Process_server_listener.accept()
client_Thread_recv = threading.Thread(target=self.Process_client_recv, args=(client_connect,))
client_Thread_recv.start()
def Process_client_recv(self, client_Thread_recv):
while True:
try:
data_json = client_Thread_recv.recv()
data = json.loads(data_json)
if data['target'] == 'Server':
if data['function'] == 'Name':
self.Process_client_link_dick[data['content']] = client_Thread_recv
else:
self.Process_client_pick(data)
except ConnectionResetError as e:
print("进程关闭" + str(e))
def Process_client_send(self, target, function, content):
connect = self.Process_client_link_dick[target]
data = {"target": target, "function": function, "content": content}
data_json = json.dumps(data)
connect.send(data_json)
def Process_client_pick(self, data):
if data['target'] == 'ALL':
for value in self.Process_client_link_dick.values():
data_json = json.dumps(data)
value.send(data_json)
else:
if data['target'] in self.Process_client_link_dick.keys():
data_json = json.dumps(data)
self.Process_client_link_dick[data['target']].send(data_json)

View File

@ -0,0 +1,85 @@
import multiprocessing
import os
import time
import socket
import json
import threading
from .Process_Client import ProcessClient
class Session_server(ProcessClient):
def __init__(self):
ProcessClient.__init__(self)
self.socker_ip = "127.0.0.1"
self.socker_port = 7868
self.server_socket = None
self.server_status = False # 服务器状态
self.link_server_Thread = threading.Thread(target=self.link_server)
self.link_server_Thread.start()
self.receive_server_Thread = threading.Thread(target=self.receive_server)
current_file_path = __file__
current_file_name = os.path.basename(current_file_path).split('.')[0]
self.Process_client_send("Server", "Name", current_file_name)
def link_server(self):
while True:
if not self.server_status:
time.sleep(1)
if self.server_socket is not None:
self.server_socket = None
try:
self.server_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
self.server_socket.connect((self.socker_ip, self.socker_port))
self.server_status = True
if not self.receive_server_Thread.is_alive():
self.receive_server_Thread.start()
except Exception as a:
self.server_status = False
print("连接错误:" + str(a))
finally:
self.Process_client_send("ALL", "server_status", self.server_status)
pass
def receive_server(self):
while self.server_status:
try:
receive_content_json = self.server_socket.recv(1024).decode('utf-8')
receive_content = json.loads(receive_content_json)
self.content_pick(receive_content)
except Exception as a:
print("客户端接收错误:" + str(a))
self.server_status = False
self.Process_client_send("ALL", "server_status", self.server_status)
def send_server(self, genre, target, content):
if self.server_status:
try:
data = {"genre": genre, "target": target, "data": content,
"datetime": time.strftime('%Y-%m-%d %H:%M:%S', time.localtime())}
data_json = json.dumps(data) + '\n'
self.server_socket.send(data_json.encode("utf-8"))
except Exception as a:
print("发送错误:" + str(a))
self.server_status = False
self.Process_client_send("ALL", "server_status", self.server_status)
def Process_client_pick(self, data):
if data['target'] in ['ALL', 'Session_server']:
match data['function']:
case 'server_status':
self.server_status = data['content']
case 'send_server':
self.send_server(data['content']['genre'], data['content']['target'], data['content']['content'])
def content_pick(self, data):
match data['genre']:
case '注册' | '登录':
self.Process_client_send("Login", "login_page_receive", data)
case '数据更新':
self.Process_client_send("File_operate", "save_data", data['data'])
case '聊天记录':
if data['data']['Type'] == 'text':
self.Process_client_send("File_operate", "save_data", {"History": data['data']})
if data['target'] == '接收':
self.Process_client_send("Chat_main", "Chat_screen_show", data['data'])

View File

@ -0,0 +1,4 @@
from .Process_Server import *
from .Process_Client import *
from .Session_server import *
from .File_operate import *

View File

@ -0,0 +1,16 @@
from .Page import *
from .Transmission import *
class start_all:
def __init__(self):
ProcessServer()
Session_server()
FileOperate(None)
app = wx.App()
LoginFrame().Show()
app.MainLoop()

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 23 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 18 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 21 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 7.1 KiB

View File

@ -0,0 +1,181 @@
import os
import pymssql
import threading
import time
from .Process_Client import *
class database(ProcessClient):
def __init__(self):
ProcessClient.__init__(self)
self.database_server = 'localhost'
self.database_user = 'Chat'
self.database_password = '123456'
self.database_port = 8972
self.database_name = 'Chat'
self.database_state = False
self.database_conn = None
self.database_cursor = None
current_file_path = __file__
current_file_name = os.path.basename(current_file_path).split('.')[0]
self.Process_client_send("Server", "Name", current_file_name)
self.link_database_thread = threading.Thread(target=self.link_database)
self.link_database_thread.start()
# 创建一个互斥锁对象
self.lock = threading.Lock()
def link_database(self):
while not self.database_state:
time.sleep(1)
try:
self.database_conn = pymssql.connect(server=self.database_server,
user=self.database_user,
password=self.database_password,
port=self.database_port,
database=self.database_name)
self.database_cursor = self.database_conn.cursor()
self.database_state = True
except pymssql.Error as a:
print(a)
def check_account_state(self, client_id, Id: int, password):
if self.database_state:
try:
state = 2
self.database_cursor.execute(f"select Id,Password from Account where Id = {Id}")
request_data = self.database_cursor.fetchall()
if len(request_data) != 0:
if request_data[0][1] == password:
state = 0
else:
state = 1
content = {"account": Id, "status": state}
data = {"client_id": client_id, "target": "客户端", "genre": "登录", "data": content}
self.Process_client_send('Session_client', 'send_client', data)
except pymssql as a:
self.database_state = False
print(a)
def sign_account(self, client_id, NetName, Password):
if self.database_state:
# 获取锁
self.lock.acquire()
try:
self.database_cursor.execute("insert into Account(NetName, Password)"
f"values ('{NetName}','{Password}')")
self.database_conn.commit()
self.database_cursor.execute(f"SELECT SCOPE_IDENTITY() AS LastInsertedId;")
Id = self.database_cursor.fetchone()[0]
# 释放锁
self.lock.release()
info = {"Id": int(Id), "NetName": NetName, "Password": Password}
content = {"client_id": client_id, "target": "客户端", "genre": "注册", "data": info}
self.Process_client_send('Session_client', 'send_client', content)
except pymssql as a:
self.lock.release()
self.database_state = False
return False
def alter_state_database(self, Id: int, sate):
if self.database_state:
try:
self.database_cursor.execute(f"update Account set State = N'{sate}' where Id = {Id}")
self.database_conn.commit()
except pymssql as a:
self.database_state = False
print(a)
def detection_data(self, Id, date):
datas = []
self.database_cursor.execute(f"select Id,Password,NetName,UpDataTime from Account where Id = {Id}")
Account_database = self.database_cursor.fetchall()
Account_content = {'Id': Account_database[0][0],
'Password': Account_database[0][1],
'NetName': Account_database[0][2],
'UpDataTime': Account_database[0][3].strftime('%Y-%m-%d %H:%M:%S')}
if Account_content['UpDataTime'] == date:
content = {"client_id": Id, "target": "客户端", "genre": "数据更新", "data": {"更新完成": Id}}
self.Process_client_send('Session_client', 'send_client', content)
return
Account_data = {"Account": Account_content}
datas.append(Account_data)
self.database_cursor.execute(
f"select ContactsId,Remark,State,UpDataTime from Contacts where UserId = {Id} and UpDataTime > '{date}'")
Contacts_database = self.database_cursor.fetchall()
for Contact in Contacts_database:
Contacts_content = {'Contact': Contact[0],
'Remark': Contact[1],
'State': Contact[2],
'UpDataTime': Contact[3].strftime('%Y-%m-%d %H:%M:%S')}
Contacts_data = {"Contacts": Contacts_content}
datas.append(Contacts_data)
self.database_cursor.execute(f"select * from History where Send = {Id} or Receive = {Id} and Time > '{date}'")
History_database = self.database_cursor.fetchall()
for History in History_database:
content = {
'Send': History[0],
'Receive': History[1],
'Type': History[2],
'Content': History[3],
'Time': History[4].strftime('%Y-%m-%d %H:%M:%S')}
History_data = {"History": content}
datas.append(History_data)
datas.append({"更新完成": Id})
for data in datas:
time.sleep(0.1)
content = {"client_id": Id, "target": "客户端", "genre": "数据更新", "data": data}
self.Process_client_send('Session_client', 'send_client', content)
def update_History(self, Send, Receive, Type, Content, Time):
if self.database_state:
try:
self.database_cursor.execute(f"insert into History(Send, Receive, Type, Content,Time)"
f"select {Send},{Receive},'{Type}',N'{Content}','{Time}'")
self.database_conn.commit()
except pymssql as a:
self.database_state = False
print(a)
def Process_client_pick(self, data):
if data['target'] in ['ALL', 'Database_formula']:
match data['function']:
case 'check_account_state':
self.check_account_state(data['content']['client_id'],
data['content']['account'],
data['content']['password'])
case 'sign_account':
self.sign_account(data['content']['client_id'],
data['content']['account'],
data['content']['password'])
case 'alter_state_database':
self.alter_state_database(data['content']['Id'],
data['content']['sate'])
case 'detection_data':
self.detection_data(data['content']['client_id'],
data['content']['date'])
case 'update_History':
self.update_History(data['content']['Send'],
data['content']['Receive'],
data['content']['Type'],
data['content']['Content'],
data['content']['Time'])

View File

@ -0,0 +1,30 @@
import json
import threading
from multiprocessing.connection import Client
class ProcessClient:
def __init__(self):
self.Process_port = 3244
self.Process_server = 'localhost'
self.Process_client_Client = Client((self.Process_server, self.Process_port))
Process_client_recv = threading.Thread(target=self.Process_client_recv)
Process_client_recv.start()
def Process_client_send(self, target, function, content):
data = {"target": target, "function": function, "content": content}
data_json = json.dumps(data)
self.Process_client_Client.send(data_json)
def Process_client_recv(self):
while True:
try:
data_json = self.Process_client_Client.recv()
data = json.loads(data_json)
self.Process_client_pick(data)
except EOFError:
print("连接已关闭")
break
def Process_client_pick(self, data):
pass

View File

@ -0,0 +1,49 @@
import json
import multiprocessing
from multiprocessing.connection import Listener
import threading
class ProcessServer:
def __init__(self):
try:
self.Process_port = 3244
self.Process_server = 'localhost'
self.Process_server_listener = Listener((self.Process_server, self.Process_port))
self.Process_client_link_dick = {}
Process_client_link_Thread = threading.Thread(target=self.Process_client_link)
Process_client_link_Thread.start()
except:
print("进程通信端口绑定失败")
def Process_client_link(self):
while True:
client_connect = self.Process_server_listener.accept()
client_Thread_recv = threading.Thread(target=self.Process_client_recv, args=(client_connect,))
client_Thread_recv.start()
def Process_client_recv(self, client_Thread_recv):
while True:
data_json = client_Thread_recv.recv()
data = json.loads(data_json)
if data['target'] == 'Server':
if data['function'] == 'Name':
self.Process_client_link_dick[data['content']] = client_Thread_recv
else:
self.Process_client_pick(data)
def Process_client_send(self, target, function, content):
connect = self.Process_client_link_dick[target]
data = {"target": target, "function": function, "content": content}
data_json = json.dumps(data)
connect.send(data_json)
def Process_client_pick(self, data):
if data['target'] == 'ALL':
for value in self.Process_client_link_dick.values():
data_json = json.dumps(data)
value.send(data_json)
else:
if data['target'] in self.Process_client_link_dick.keys():
data_json = json.dumps(data)
self.Process_client_link_dick[data['target']].send(data_json)

View File

@ -0,0 +1,127 @@
import os
import random
import string
import time
import socket
import json
import threading
from .Process_Client import *
class link_client(ProcessClient):
def __init__(self):
ProcessClient.__init__(self)
self.server_host = "127.0.0.1"
self.server_port = 7868
self.server_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
self.server_socket.bind((self.server_host, self.server_port))
self.server_socket.listen()
self.client_socket_dict = {}
self.client_max_id = 0
current_file_path = __file__
current_file_name = os.path.basename(current_file_path).split('.')[0]
self.Process_client_send("Server", "Name", current_file_name)
self.link_client_Thread = threading.Thread(target=self.link_client)
self.link_client_Thread.start()
def link_client(self):
while True:
try:
client_socket, client_address = self.server_socket.accept()
self.client_max_id += 1
client_id = ''.join(random.choice(string.ascii_letters) for _ in range(10)) + str(self.client_max_id)
self.client_socket_dict[client_id] = client_socket
recv_client_Thread = threading.Thread(target=self.recv_client, args=(client_socket,), daemon=True)
recv_client_Thread.start()
except:
pass
def send_client(self, client_id, genre, target, content):
client_socket = self.client_socket_dict[client_id]
try:
data = {"genre": genre, "target": target, "data": content,
"datetime": time.strftime('%Y-%m-%d %H:%M:%S', time.localtime())}
data_json = json.dumps(data) + '\n'
client_socket.send(data_json.encode("utf-8"))
except:
client_socket.close()
def pick_data(self, client_id, data):
match data['genre']:
case '登录':
content = {'client_id': client_id, 'account': data['data']['account'],
'password': data['data']['password']}
self.Process_client_send("Database_formula", "check_account_state", content)
case '注册':
content = {'client_id': client_id, 'account': data['data']['account'],
'password': data['data']['password']}
self.Process_client_send("Database_formula", "sign_account", content)
case '数据更新':
content = {'client_id': client_id, 'date': data['data']}
self.Process_client_send("Database_formula", "detection_data", content)
case '聊天记录':
Send = client_id
Receive = data['target']
Time = data['datetime']
data = data['data']
Type = data['Type']
Content = data['content']
content = {'Send': Send, 'Receive': Receive, 'Time': Time, 'Type': Type, 'Content': Content}
self.Process_client_send("Database_formula", "update_History", content)
self.send_client(Send, "聊天记录", "发送", content)
if Receive in self.client_socket_dict:
self.send_client(Receive, "聊天记录", "接收", content)
def recv_client(self, client_socket):
state = True
while state:
try:
data_json = client_socket.recv(1024).decode('utf-8')
data = json.loads(data_json)
client_Id = self.find_client(client_socket, None)
self.pick_data(client_Id, data)
except:
try:
client_socket.close()
finally:
state = False
self.find_client(client_socket, None)
client_id = self.find_client(client_socket, None)
del self.client_socket_dict[client_id]
if client_id.isdigit():
self.Process_client_send("Database_formula", "alter_state_database",
{"Id": client_id, "sate": 0})
def Process_client_pick(self, data):
if data['target'] in ['ALL', 'Session_client']:
match data['function']:
case 'send_client':
client_id = data['content']['client_id']
genre = data['content']['genre']
target = data['content']['target']
content = data['content']['data']
if data['content']['genre'] == '登录':
if content['account'] not in self.client_socket_dict:
if content['status'] == 0:
client_socket = self.find_client(None, client_id)
del self.client_socket_dict[client_id]
client_id = content['account']
self.client_socket_dict[client_id] = client_socket
if client_id.isdigit():
self.Process_client_send("Database_formula", "alter_state_database",
{"Id": client_id, "sate": 1})
else:
return
self.send_client(client_id, genre, target, content)
def find_client(self, client_socket, client_id):
if client_id is None:
for key, value in self.client_socket_dict.items():
if value == client_socket:
return key
elif client_socket is None:
for key, value in self.client_socket_dict.items():
if key == client_id:
return value

View File

@ -0,0 +1,4 @@
from .Process_Server import *
from .Process_Client import *
from .Session_client import *
from .Database_formula import *

View File

@ -0,0 +1,11 @@
from .Transmission import *
class Server_main:
def __init__(self):
ProcessServer()
database()
link_client()

View File

@ -0,0 +1,4 @@
from Client import start_all
if __name__ == '__main__':
start_all()

View File

@ -0,0 +1,4 @@
from Server import Server_main
if __name__ == '__main__':
Server_main()

View File

@ -0,0 +1,6 @@
from Client import start_all
from Server import Server_main
if __name__ == '__main__':
Server_main()
start_all()

View File

@ -1,30 +0,0 @@
import wx
import wx.richtext as rt
class MyFrame(wx.Frame):
def __init__(self, parent, id, title):
wx.Frame.__init__(self, parent, id, title, size=(400, 300))
panel = wx.Panel(self)
vbox = wx.BoxSizer(wx.VERTICAL)
# 创建 RichTextCtrl
self.rtc = rt.RichTextCtrl(panel, style=wx.VSCROLL | wx.HSCROLL | wx.NO_BORDER | wx.WANTS_CHARS)
self.rtc.BeginFontSize(12)
self.rtc.WriteText("Here is some text, and here is an image: ")
self.rtc.EndFontSize()
# 插入图片
image = wx.Bitmap('path_to_your_image.png', wx.BITMAP_TYPE_PNG)
self.rtc.WriteImage(image)
vbox.Add(self.rtc, 1, flag=wx.EXPAND)
panel.SetSizer(vbox)
self.Show()
if __name__ == '__main__':
app = wx.App()
MyFrame(None, -1, 'Insert Image in RichTextCtrl')
app.MainLoop()