将功能都模块化了但是没有解决进程之间的通信问题

This commit is contained in:
lsy2246 2024-04-16 00:45:21 +08:00
parent 0e50aaa7da
commit 26922f4fe9
15 changed files with 491 additions and 201 deletions

View File

@ -1,11 +1,14 @@
import wx
import wx.aui
import wx.lib.scrolledpanel as scrolled
import threading
import time
import multiprocessing
class ChatFrame(wx.Frame):
def __init__(self):
super().__init__(None, size=(1000, 700))
super().__init__(None, size=(800, 600), title="客户端")
ChatMain_Panel = wx.Panel(self, style=wx.BORDER_SUNKEN)
ChatMain_box = wx.BoxSizer(wx.HORIZONTAL)
@ -14,7 +17,7 @@ class ChatFrame(wx.Frame):
Function_Panel = wx.Panel(ChatMain_Panel, style=wx.BORDER_RAISED)
Function_box = wx.BoxSizer(wx.VERTICAL)
Function_Panel.SetSizer(Function_box)
Function_Panel.SetBackgroundColour(wx.Colour(242, 242, 242))
Function_Panel.SetBackgroundColour(wx.Colour(240, 240, 240))
image_chat = r'./Client/image/chat.png'
Chat_bitmap = wx.Bitmap(image_chat, wx.BITMAP_TYPE_PNG)
@ -23,7 +26,7 @@ class ChatFrame(wx.Frame):
Function_box.Add(Chat_bitmap_static, 1, wx.EXPAND, 0)
Chat_bitmap_static.Bind(wx.EVT_LEFT_DOWN, self.click_chat_button)
Function_box.AddSpacer(30) # 调整这个数字以改变间距大小
Function_box.AddSpacer(20) # 调整这个数字以改变间距大小
image_connect = r'./Client/image/connect.png'
connect_bitmap = wx.Bitmap(image_connect, wx.BITMAP_TYPE_PNG)
@ -32,7 +35,7 @@ class ChatFrame(wx.Frame):
Function_box.Add(connect_bitmap_static, 1, wx.EXPAND, 0)
connect_bitmap_static.Bind(wx.EVT_LEFT_DOWN, self.click_connect_button)
Function_box.AddSpacer(28) # 调整这个数字以改变间距大小
Function_box.AddSpacer(20) # 调整这个数字以改变间距大小
image_find = r'./Client/image/find.png'
find_bitmap = wx.Bitmap(image_find, wx.BITMAP_TYPE_PNG)
@ -41,7 +44,7 @@ class ChatFrame(wx.Frame):
Function_box.Add(find_bitmap_static, 1, wx.EXPAND, 0)
find_bitmap_static.Bind(wx.EVT_LEFT_DOWN, self.click_find_button)
Function_box.AddSpacer(340) # 调整这个数字以改变间距大小
Function_box.AddSpacer(280) # 调整这个数字以改变间距大小
image_site = r'./Client/image/site.png'
site_bitmap = wx.Bitmap(image_site, wx.BITMAP_TYPE_PNG)
@ -56,29 +59,65 @@ class ChatFrame(wx.Frame):
operate_box = wx.BoxSizer(wx.VERTICAL)
chat_page = self.ChatPage(ChatMain_Panel) # 将 ChatMain_Panel 作为 ChatPage 的 parent
operate_box.Add(chat_page, 1, wx.EXPAND, 0)
self.chat_page = self.ChatPage(ChatMain_Panel) # 将 ChatMain_Panel 作为 ChatPage 的 parent
operate_box.Add(self.chat_page, 1, wx.EXPAND, 5)
self.chat_page.Hide()
ChatMain_box.Add(operate_box, 0, wx.EXPAND, 0)
self.connect_page = self.ConnectPage(ChatMain_Panel)
operate_box.Add(self.connect_page, 1, wx.EXPAND, 5)
self.connect_page.Hide()
self.site_page = self.SitePage(ChatMain_Panel)
operate_box.Add(self.site_page, 1, wx.EXPAND, 5)
self.site_page.Hide()
self.find_page = self.FindPage(ChatMain_Panel)
operate_box.Add(self.find_page, 1, wx.EXPAND, 5)
self.find_page.Hide()
ChatMain_box.Add(operate_box, 1, wx.EXPAND, 5)
self.chat_page.Show()
ChatMain_Panel.SetSizer(ChatMain_box)
def click_chat_button(self, event):
print("点击了聊天")
self.chat_page.Hide()
self.connect_page.Hide()
self.site_page.Hide()
self.find_page.Hide()
self.chat_page.Show()
self.Layout()
def click_connect_button(self, event):
print("点击了联系人")
self.chat_page.Hide()
self.connect_page.Hide()
self.site_page.Hide()
self.find_page.Hide()
self.connect_page.Show()
self.Layout()
def click_site_button(self, event):
print("点击了设置")
self.chat_page.Hide()
self.connect_page.Hide()
self.site_page.Hide()
self.find_page.Hide()
self.site_page.Show()
self.Layout()
def click_find_button(self, event):
print("点击了查找")
self.chat_page.Hide()
self.connect_page.Hide()
self.site_page.Hide()
self.find_page.Hide()
self.find_page.Show()
self.Layout()
class ChatPage(wx.Panel):
def __init__(self, parent):
wx.Panel.__init__(self, parent, style=wx.BORDER_SUNKEN)
ChatPage_main_box = wx.BoxSizer(wx.HORIZONTAL)
self.chat_window_id = []
ChatPage_Contact_person_box = wx.BoxSizer(wx.VERTICAL)
self.ChatPage_Contact_person_panel = scrolled.ScrolledPanel(self, -1, style=wx.SUNKEN_BORDER)
@ -86,18 +125,89 @@ class ChatFrame(wx.Frame):
self.ChatPage_Contact_person_panel.SetSizer(wx.BoxSizer(wx.VERTICAL))
ChatPage_Contact_person_box.Add(self.ChatPage_Contact_person_panel, proportion=1, flag=wx.EXPAND | wx.ALL,
border=5)
ChatPage_main_box.Add(ChatPage_Contact_person_box, 0, wx.EXPAND, 0)
ChatPage_main_box.Add(ChatPage_Contact_person_box, proportion=1, flag=wx.EXPAND | wx.ALL, border=5)
self.chat_tab = wx.aui.AuiNotebook(self, style=wx.aui.AUI_NB_CLOSE_ON_ALL_TABS)
ChatPage_main_box.Add(self.chat_tab, proportion=3, flag=wx.EXPAND | wx.ALL, border=5)
self.SetSizer(ChatPage_main_box)
def ChatPage_add_Contact_person(self, Id, Remark, info):
ChatPage_add_Contact_person_box = wx.BoxSizer(wx.VERTICAL)
def ChatPage_add_Contact_person(self,NetName,info):
ChatPage_add_Contact_person_top_box = wx.BoxSizer(wx.HORIZONTAL)
if len(Remark) > 6:
Remark = Remark[:6] + "..."
else:
Remark += ''.join([" " for i in range(max(0, 9 - len(Remark)))])
ChatPage_add_Contact_person_NetName = wx.StaticText(self.ChatPage_Contact_person_panel, -1, Remark)
ChatPage_add_Contact_person_top_box.Add(ChatPage_add_Contact_person_NetName, 0, wx.ALIGN_LEFT, 0)
ChatPage_add_Contact_person_top_box.AddSpacer(20)
#self.ChatPage_Contact_person_panel.GetSizer().Add(, 0, wx.ALL, 5)
self.ChatPage_Contact_person_panel.Layout() # 重新布局滚动面板
ChatPage_add_Contact_person_date = wx.StaticText(self.ChatPage_Contact_person_panel, -1,
time.strftime("%Y/%m/%d", time.localtime()))
ChatPage_add_Contact_person_top_box.Add(ChatPage_add_Contact_person_date, 0, wx.ALIGN_CENTER_VERTICAL, 0)
ChatPage_add_Contact_person_box.Add(ChatPage_add_Contact_person_top_box, 0, wx.EXPAND, 0)
if len(info) > 10:
info = info[:10] + "..."
ChatPage_add_Contact_person_info = wx.StaticText(self.ChatPage_Contact_person_panel, -1, info)
ChatPage_add_Contact_person_box.Add(ChatPage_add_Contact_person_info, 0, wx.ALIGN_LEFT, 0)
self.ChatPage_Contact_person_panel.GetSizer().Add(ChatPage_add_Contact_person_box, 0, wx.ALL, 5)
self.ChatPage_Contact_person_panel.Layout()
self.ChatPage_Contact_person_panel.SetupScrolling()
ChatPage_add_Contact_person_NetName.Bind(wx.EVT_LEFT_DOWN,
lambda event: self.ChatPage_add_Contact_tab(Id, Remark))
def ChatPage_add_Contact_tab(self, Id, Remark):
if Id in self.chat_window_id:
return
self.chat_window_id.append(Id)
chat_panel = wx.Panel(self.chat_tab)
chat_box = wx.BoxSizer(wx.VERTICAL)
chat_receive_box = wx.BoxSizer(wx.HORIZONTAL)
chat_receive_text = wx.TextCtrl(chat_panel, style=wx.TE_MULTILINE | wx.TE_READONLY)
chat_receive_box.Add(chat_receive_text, 1, wx.EXPAND, 0)
chat_box.Add(chat_receive_box, 2, wx.EXPAND, 0)
toolbar = wx.ToolBar(chat_panel)
toolbar.SetToolBitmapSize((16, 16)) # Set the size of the toolbar icons
toolbar.AddTool(wx.ID_ANY, "Tool", wx.Bitmap(wx.Bitmap(r'./Client/image/picture.png')))
toolbar.AddTool(wx.ID_ANY, "Tool", wx.Bitmap(wx.Bitmap(r'./Client/image/file.png')))
toolbar.AddTool(wx.ID_ANY, "Tool", wx.Bitmap(wx.Bitmap(r'./Client/image/speech.png')))
toolbar.AddTool(wx.ID_ANY, "Tool", wx.Bitmap(wx.Bitmap(r'./Client/image/video.png')))
toolbar.Realize()
toolbar.SetSize((-1, 30)) # Set the size of the toolbar
chat_box.Add(toolbar, 0, wx.EXPAND)
chat_send_box = wx.BoxSizer(wx.HORIZONTAL)
chat_send_text = wx.TextCtrl(chat_panel, style=wx.TE_MULTILINE)
chat_send_box.Add(chat_send_text, 1, wx.EXPAND, 0)
chat_box.Add(chat_send_box, 1, wx.EXPAND, 0)
send_button = wx.Button(chat_panel, label='发送') # Create a send button
chat_send_box.Add(send_button, 0, wx.EXPAND | wx.LEFT, 5) # Add the button to the send box
chat_panel.SetSizer(chat_box)
self.chat_tab.AddPage(chat_panel, Remark, select=True)
class ConnectPage(wx.Panel):
def __init__(self, parent):
wx.Panel.__init__(self, parent)
print("联系人")
class SitePage(wx.Panel):
def __init__(self, parent):
wx.Panel.__init__(self, parent)
print("设置")
class FindPage(wx.Panel):
def __init__(self, parent):
wx.Panel.__init__(self, parent)
print("查找")

View File

@ -1,3 +1,5 @@
import json
import multiprocessing
import wx
import threading
import time
@ -6,6 +8,11 @@ import time
class LoginFrame(wx.Frame):
def __init__(self):
wx.Frame.__init__(self, None, id=1001, title='登录', pos=wx.DefaultPosition, size=(380, 300))
self.queue_in = multiprocessing.Queue()
self.queue_out = multiprocessing.Queue()
self.queue_thread = threading.Thread(target=self.queue_recv)
self.queue_thread.start()
# 创建菜单栏
menu_bar = wx.MenuBar()
@ -42,8 +49,8 @@ class LoginFrame(wx.Frame):
# 创建注册面板
self.sizer = wx.BoxSizer(wx.VERTICAL)
self.login_panel = self.LoginPanel(self)
self.register_panel = self.RegisterPanel(self)
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)
@ -52,6 +59,10 @@ class LoginFrame(wx.Frame):
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):
@ -84,111 +95,170 @@ class LoginFrame(wx.Frame):
self.register_panel.Hide()
self.Layout()
class LoginPanel(wx.Panel):
def __init__(self, parent):
super().__init__(parent)
# 主盒子
LoginPanel_main_box = wx.BoxSizer(wx.VERTICAL)
def login_page_receive(self, receive_content):
if receive_content["genre"] == '登录':
match receive_content["data"]:
case 0:
# 关闭当前框架
self.Close()
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)
# 顶部盒子,目前只放了软件名
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)
def queue_send(self, function, content):
data = json.dumps({"function": function, "content": content})
self.queue_out.put(data)
# 中部盒子,放账号和密码
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)
def queue_recv(self):
while True:
try:
data_json = self.queue_in.get()
data = json.loads(data_json)
self.queue_pick(data)
except Exception as e:
print("Error in queue_recv:", e)
# 底部盒子
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) # 将底部盒子添加到主盒子中,使其填满剩余空间
def queue_pick(self, data):
match data["function"]:
case "server_status":
self.server_status = data["content"]
case "login_page_receive":
self.login_page_receive(data["content"])
self.SetSizer(LoginPanel_main_box)
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}
self.queue_send("send_server", data)
class RegisterPanel(wx.Panel):
def __init__(self, parent):
super().__init__(parent)
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}
self.queue_send("send_server", data)
# 主盒子
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)
class LoginPanel(wx.Panel):
def __init__(self, parent):
super().__init__(parent)
# 主盒子
LoginPanel_main_box = wx.BoxSizer(wx.VERTICAL)
# 中部盒子,放账号和密码
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)
# 顶部盒子,目前只放了软件名
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)
# 底部盒子
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) # 将底部盒子添加到主盒子中,使其填满剩余空间
# 中部盒子,放账号和密码
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)
self.SetSizer(RegisterPanel_main_box)
# 底部盒子
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

@ -1,3 +1,4 @@
import multiprocessing
import time
import socket
import json
@ -10,12 +11,41 @@ class Session_server:
self.socker_port = 8000
self.server_socket = None
self.server_status = False # 服务器状态
self.queue_in = multiprocessing.Queue()
self.queue_out = multiprocessing.Queue()
self.queue_thread = threading.Thread(target=self.queue_recv)
self.queue_thread.start()
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)
def queue_send(self, function, content):
data = json.dumps({"function": function, "content": content})
self.queue_out.put(data)
print(data)
def queue_recv(self):
while True:
try:
data_json = self.queue_in.get()
data = json.loads(data_json)
self.queue_pick(data)
except Exception as e:
print("Error in queue_recv:", e)
def queue_pick(self, data):
match data["function"]:
case "server_status":
self.server_status = data["content"]
case "send_server":
genre = data["content"]["genre"]
target = data["content"]["target"]
content = data["content"]["content"]
self.send_server(genre, target, content)
def link_server(self):
while True:
if not self.server_status:
@ -31,9 +61,8 @@ class Session_server:
except Exception as a:
self.server_status = False
print("连接错误:" + str(a))
def login_page_receive(self, receive_content):
pass
finally:
self.queue_send("server_status", self.server_status)
def receive_server(self):
while self.server_status:
@ -41,11 +70,12 @@ class Session_server:
receive_content_json = self.server_socket.recv(1024).decode('utf-8')
receive_content = json.loads(receive_content_json)
if receive_content["genre"] in ['注册', '登录']:
self.login_page_receive(receive_content)
self.queue_send("login_page_receive", receive_content)
print(receive_content)
except Exception as a:
print("接收错误:" + str(a))
self.server_status = False
self.queue_send("server_status", self.server_status)
def send_server(self, genre, target, content):
if self.server_status:
@ -57,4 +87,4 @@ class Session_server:
except Exception as a:
print("发送错误:" + str(a))
self.server_status = False
self.queue_send("server_status", self.server_status)

View File

@ -1,48 +1,14 @@
from .Login import *
from .Session_server import *
from .Chat_main import *
class Client_main(LoginFrame, Session_server):
class start_all:
def __init__(self):
Session_server.__init__(self) # 与服务器会话
LoginFrame.__init__(self)
# 主页按钮绑定
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)
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 = "登录"
self.send_server(genre=genre, target=target, content=content)
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 = "注册"
self.send_server(genre=genre, target=target, content=content)
def login_page_receive(self, receive_content):
if receive_content["genre"] == '登录':
match receive_content["data"]:
case 0:
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)
Session_server()
app = wx.App(False)
frame = LoginFrame()
frame.Show(True)
app.MainLoop()

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.3 KiB

After

Width:  |  Height:  |  Size: 2.8 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.6 KiB

After

Width:  |  Height:  |  Size: 2.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 23 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.9 KiB

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: 21 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 7.1 KiB

View File

@ -1,8 +1,5 @@
import wx
from Client import Client_main
from Client import start_all
if __name__ == '__main__':
app = wx.App()
frame = Client_main()
frame.Show()
app.MainLoop()
start_all()

View File

@ -1,34 +1,151 @@
# 服务端
import socket
import cv2
import pickle
import struct
import wx
import wx.aui
import wx.lib.scrolledpanel as scrolled
import time
HOST = '127.0.0.1' # 服务器IP地址
PORT = 65432 # 监听端口
# 创建Socket
server_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
server_socket.bind((HOST, PORT))
server_socket.listen(5)
class ChatFrame(wx.Frame):
def __init__(self):
super().__init__(None, size=(1000, 700))
# 接受客户端连接
connection, address = server_socket.accept()
print('Connected by', address)
ChatMain_Panel = wx.Panel(self, style=wx.BORDER_SUNKEN)
ChatMain_box = wx.BoxSizer(wx.HORIZONTAL)
ChatMain_Panel.SetSizer(ChatMain_box)
# 使用OpenCV捕获视频
cap = cv2.VideoCapture(0)
Function_Panel = wx.Panel(ChatMain_Panel, style=wx.BORDER_RAISED)
Function_box = wx.BoxSizer(wx.VERTICAL)
Function_Panel.SetSizer(Function_box)
Function_Panel.SetBackgroundColour(wx.Colour(242, 242, 242))
while True:
ret, frame = cap.read()
# 将视频帧序列化
data = pickle.dumps(frame)
# 将序列化的数据封装成一个结构体
message = struct.pack("Q", len(data)) + data
# 发送数据到客户端
connection.sendall(message)
image_chat = r'./Client/image/chat.png'
Chat_bitmap = wx.Bitmap(image_chat, wx.BITMAP_TYPE_PNG)
Chat_bitmap_static = wx.StaticBitmap(Function_Panel, bitmap=Chat_bitmap, style=wx.BORDER_RAISED)
Chat_bitmap_static.SetToolTip("聊天")
Function_box.Add(Chat_bitmap_static, 1, wx.EXPAND, 0)
Chat_bitmap_static.Bind(wx.EVT_LEFT_DOWN, self.click_chat_button)
# 释放资源
connection.close()
server_socket.close()
cap.release()
Function_box.AddSpacer(30) # 调整这个数字以改变间距大小
image_connect = r'./Client/image/connect.png'
connect_bitmap = wx.Bitmap(image_connect, wx.BITMAP_TYPE_PNG)
connect_bitmap_static = wx.StaticBitmap(Function_Panel, bitmap=connect_bitmap, style=wx.BORDER_RAISED)
connect_bitmap_static.SetToolTip("通讯录")
Function_box.Add(connect_bitmap_static, 1, wx.EXPAND, 0)
connect_bitmap_static.Bind(wx.EVT_LEFT_DOWN, self.click_connect_button)
Function_box.AddSpacer(28) # 调整这个数字以改变间距大小
image_find = r'./Client/image/find.png'
find_bitmap = wx.Bitmap(image_find, wx.BITMAP_TYPE_PNG)
find_bitmap_static = wx.StaticBitmap(Function_Panel, bitmap=find_bitmap, style=wx.BORDER_RAISED)
find_bitmap_static.SetToolTip("查找")
Function_box.Add(find_bitmap_static, 1, wx.EXPAND, 0)
find_bitmap_static.Bind(wx.EVT_LEFT_DOWN, self.click_find_button)
Function_box.AddSpacer(340) # 调整这个数字以改变间距大小
image_site = r'./Client/image/site.png'
site_bitmap = wx.Bitmap(image_site, wx.BITMAP_TYPE_PNG)
site_bitmap_static = wx.StaticBitmap(Function_Panel, bitmap=site_bitmap, style=wx.BORDER_RAISED)
site_bitmap_static.SetToolTip("设置")
Function_box.Add(site_bitmap_static, 1, wx.EXPAND, 0)
site_bitmap_static.Bind(wx.EVT_LEFT_DOWN, self.click_site_button)
Function_box.Fit(Function_Panel) # 调整面板大小以适应图像
ChatMain_box.Add(Function_Panel, 0, wx.EXPAND | wx.ALL, 5)
operate_box = wx.BoxSizer(wx.VERTICAL)
chat_page = self.ChatPage(ChatMain_Panel) # 将 ChatMain_Panel 作为 ChatPage 的 parent
operate_box.Add(chat_page, 1, wx.EXPAND, 5)
ChatMain_box.Add(operate_box, 1, wx.EXPAND, 5)
ChatMain_Panel.SetSizer(ChatMain_box)
def click_chat_button(self, event):
print("点击了聊天")
def click_connect_button(self, event):
print("点击了联系人")
def click_site_button(self, event):
print("点击了设置")
def click_find_button(self, event):
print("点击了查找")
class ChatPage(wx.Panel):
def __init__(self, parent):
wx.Panel.__init__(self, parent, style=wx.BORDER_SUNKEN)
ChatPage_main_box = wx.BoxSizer(wx.HORIZONTAL)
self.ChatPage_add_Contact_text_box_dick = {}
ChatPage_Contact_person_box = wx.BoxSizer(wx.VERTICAL)
self.ChatPage_Contact_person_panel = scrolled.ScrolledPanel(self, -1, style=wx.SUNKEN_BORDER)
self.ChatPage_Contact_person_panel.SetupScrolling() # 启用滚动功能
self.ChatPage_Contact_person_panel.SetSizer(wx.BoxSizer(wx.VERTICAL))
ChatPage_Contact_person_box.Add(self.ChatPage_Contact_person_panel, proportion=1, flag=wx.EXPAND | wx.ALL,
border=5)
ChatPage_main_box.Add(ChatPage_Contact_person_box, 1, wx.EXPAND, 5)
self.ChatPage_add_Contact_person(11, "lsy", "asdasddsa")
self.chat_tab = wx.aui.AuiNotebook(self,style=wx.aui.AUI_NB_CLOSE_ON_ALL_TABS)
ChatPage_main_box.Add(self.chat_tab, 1, wx.EXPAND, 0)
self.SetSizer(ChatPage_main_box)
def ChatPage_add_Contact_person(self, Id, Remark, info):
ChatPage_add_Contact_person_box = wx.BoxSizer(wx.VERTICAL)
ChatPage_add_Contact_person_top_box = wx.BoxSizer(wx.HORIZONTAL)
if len(Remark) > 6:
Remark = Remark[:6] + "..."
else:
Remark += ''.join([" " for i in range(max(0, 9 - len(Remark)))])
ChatPage_add_Contact_person_NetName = wx.StaticText(self.ChatPage_Contact_person_panel, -1, Remark)
ChatPage_add_Contact_person_top_box.Add(ChatPage_add_Contact_person_NetName, 0, wx.ALIGN_LEFT, 0)
ChatPage_add_Contact_person_top_box.AddSpacer(20)
ChatPage_add_Contact_person_date = wx.StaticText(self.ChatPage_Contact_person_panel, -1,
time.strftime("%Y/%m/%d", time.localtime()))
ChatPage_add_Contact_person_top_box.Add(ChatPage_add_Contact_person_date, 0, wx.ALIGN_CENTER_VERTICAL, 0)
ChatPage_add_Contact_person_box.Add(ChatPage_add_Contact_person_top_box, 0, wx.EXPAND, 0)
if len(info) > 10:
info = info[:10] + "..."
ChatPage_add_Contact_person_info = wx.StaticText(self.ChatPage_Contact_person_panel, -1, info)
ChatPage_add_Contact_person_box.Add(ChatPage_add_Contact_person_info, 0, wx.ALIGN_LEFT, 0)
self.ChatPage_Contact_person_panel.GetSizer().Add(ChatPage_add_Contact_person_box, 0, wx.ALL, 5)
self.ChatPage_Contact_person_panel.Layout()
self.ChatPage_Contact_person_panel.SetupScrolling()
ChatPage_add_Contact_person_NetName.Bind(wx.EVT_LEFT_DOWN, lambda event: self.ChatPage_add_Contact_tab(Id, Remark))
def ChatPage_add_Contact_tab(self, Id, Remark):
for i in range(self.chat_tab.GetPageCount()):
if self.chat_tab.GetPageText(i) == Remark:
return
chat_panel = wx.Panel(self.chat_tab)
chat_box = wx.BoxSizer(wx.VERTICAL)
chat_receive_box = wx.BoxSizer(wx.HORIZONTAL)
chat_receive_text = wx.TextCtrl(chat_panel, style=wx.TE_MULTILINE)
chat_receive_box.Add(chat_receive_text, 0, wx.EXPAND, 0)
chat_box.Add(chat_receive_box, 1, wx.EXPAND, 0)
self.chat_tab.AddPage(chat_panel, wx.Panel(), Remark, select=True) # 将第三个参数改为 wx.Panel(),表示每个页面使用一个新的 Panel 承载控件
chat_panel.SetSizer(chat_box)
app = wx.App()
frame = ChatFrame()
frame.Show()
app.MainLoop()

View File

@ -17,7 +17,7 @@ payload_size = struct.calcsize("Q")
while True:
# 从服务器接收数据
while len(data) < payload_size:
packet = client_socket.recv(4*1024)
packet = client_socket.recv(4*10240)
if not packet: break
data += packet
packed_msg_size = data[:payload_size]

View File

@ -3,7 +3,7 @@ from Client.Chat_main import ChatFrame
if __name__ == '__main__':
app = wx.App()
frame = ChatFrame()
frame = ChatFrame("lsy")
frame.Show()
app.MainLoop()