基于Python的网络聊天软件的设计与实现

# 服务端程序
import socket
import threading
from tkinter import *
from tkinter import messagebox
import matplotlib.pyplot as plt
import numpy as np
from math import *
from matplotlib.backends.backend_tkagg import FigureCanvasTkAgg
# 创建套接字并绑定地址
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.bind((socket.gethostbyname(socket.gethostname()), 1234))
s.listen(1)
clientsocket, clientaddress = s.accept()

send_flag = False
running = True
def receive_messages():
    global running
    while running:
        try:
            data = clientsocket.recv(1024).decode()
            if data:
                chat_message.configure(state=NORMAL)
                chat_message.insert(END, "客户端:"+data + '\n')
                chat_message.configure(state=DISABLED)
            if data.startswith("Function:y="):
                function_str=data[11:]
                try:
                    x = np.linspace(-10, 10, 100)  # 创建一个包含-10到10的100个数据点的数组
                    if "x" not in function_str:
                        raise ValueError("函数中未包含自变量 x")
                    y = eval(function_str)  # 计算函数在x值上的y值
                    dy_dx = np.gradient(y, x)  # 计算函数在x值上的一阶导数
                    # 绘制函数及其一阶导数的图像
                    plt.figure()
                    plt.subplot(2, 1, 1)
                    plt.plot(x, y)
                    plt.title('Function')
                    plt.xlabel('x')
                    plt.ylabel('y')
                    plt.subplot(2, 1, 2)
                    plt.plot(x, dy_dx)
                    plt.title('First Derivative')
                    plt.xlabel('x')
                    plt.ylabel("dy/dx")
                    plt.tight_layout()
                    plt.show()
                except Exception as e:
                    chat_message.insert(END, "计算出错:" + str(e) + '\n')
                
        except ConnectionError:
            break

# 将表达式转化为函数
def f(x, expression):
    func = np.vectorize(lambda x: eval(expression))
    return func(x)


# 求取函数的一阶导函数
def g(x, expression):
    return np.gradient(f(x, expression), x)
def send_message():
    global send_flag
    if send_flag:
        message = input_message.get("1.0", END).strip()
        if message:
            input_message.delete("1.0", END)
            chat_message.configure(state=NORMAL)
            chat_message.insert(END,"我:"+message + '\n')
            chat_message.configure(state=DISABLED)
            clientsocket.send(message.encode())
            send_flag = False
def show_graph():
    expression = input_message.get("1.0", END)
    expression = expression.strip()  # 去除空格和换行符
    if expression.startswith('y='):
        expression = expression[2:]

    if 'sin' in expression or 'cos' in expression:
        period = 4 * np.pi / abs(eval(expression.split('sin')[1] if 'sin' in expression else expression.split('cos')[1], {'x': 1}))
        x = np.linspace(-period / 2, period / 2, 100)  # 定义自变量的范围,共有 100 个点
    else:
        x = np.linspace(-10, 10, 50)  # 定义自变量的范围,共有 201 个点
        
    y = f(x, expression)  # 计算原函数的因变量的取值
    z = g(x, expression)  # 计算一阶导函数的因变量的取值

    # 绘制原函数和一阶导函数的图像
    fig, ax = plt.subplots(nrows=1, ncols=2, figsize=(10, 4))

    ax[0].plot(x, y)  # 绘制原函数图像
    ax[0].set_ylabel('y')  # 设置 y 轴标签
    ax[0].set_xlabel('x')  # 设置 x 轴标签
    ax[0].set_title('函数图像')  # 设置子图标题

    ax[1].plot(x, z)  # 绘制一阶导函数图像
    ax[1].set_ylabel('dy/dx')  # 设置 y 轴标签
    ax[1].set_xlabel('x')  # 设置 x 轴标签
    ax[1].set_title('一阶导数图像')  # 设置子图标题

    plt.tight_layout()  # 自动调整子图布局

    new_window = Toplevel()  # 创建新窗口
    new_window.title('图像')  # 设置窗口标题
    canvas = FigureCanvasTkAgg(fig, master=new_window)  # 绘制画布
    canvas.draw()
    canvas.get_tk_widget().pack(side=TOP, fill=BOTH, expand=1)  # 将画布添加到窗口中
    new_window.focus_set()  # 聚焦到新窗口
    new_window.grab_set()  # 捕获所有事件
    new_window.mainloop()  # 进入消息循环
def update_chat_records():
    global chat_listbox  
    chat_listbox.delete(0, END)
    cursor.execute("SELECT * FROM chat_records")
    records = cursor.fetchall()
    for record in records:
        chat_listbox.insert(END, f"{record[1]}: {record[2]}")

def show_chat_records():
    global chat_listbox  
    new_window = Toplevel()
    new_window.title('聊天记录')
    new_window.geometry('500x400')

    chat_listbox = Listbox(new_window, width=60, height=20)
    chat_listbox.pack(pady=10)

    scrollbar = Scrollbar(new_window)
    scrollbar.pack(side=RIGHT, fill=Y)

    chat_listbox.config(yscrollcommand=scrollbar.set)
    scrollbar.config(command=chat_listbox.yview)

    update_chat_records()

    def close_chat_records():
        new_window.destroy()

    new_window.protocol("WM_DELETE_WINDOW", close_chat_records)
    new_window.mainloop()

def delete_chat_records():
    cursor.execute("DELETE FROM chat_records")
    conn.commit()
    update_chat_records()
    messagebox.showinfo("删除聊天记录", "成功删除聊天记录!")

def modify_chat_record():
    selected_index = chat_listbox.curselection()
    if selected_index:
        selected_record = chat_listbox.get(selected_index[0])
        message_parts = selected_record.split(": ")
        if len(message_parts) == 2:
            sender = message_parts[0]
            message = message_parts[1]

            modify_window = Toplevel()
            modify_window.title('修改聊天记录')
            modify_window.geometry('300x150')

            sender_label = Label(modify_window, text="发送者:")
            sender_label.pack()
            sender_entry = Entry(modify_window)
            sender_entry.insert(END, sender)
            sender_entry.pack()

            message_label = Label(modify_window, text="消息内容:")
            message_label.pack()
            message_entry = Entry(modify_window)
            message_entry.insert(END, message)
            message_entry.pack()

            def save_changes():
                new_sender = sender_entry.get()
                new_message = message_entry.get()

                cursor.execute("UPDATE chat_records SET sender = ?, message = ? WHERE sender = ? AND message = ?",
                               (new_sender, new_message, sender, message))
                conn.commit()
                update_chat_records()
                messagebox.showinfo("修改聊天记录", "成功修改聊天记录!")
                modify_window.destroy()

            save_button = Button(modify_window, text="保存", command=save_changes)
            save_button.pack()

            modify_window.mainloop()
        else:
            messagebox.showerror("修改聊天记录", "无法解析选定的聊天记录!")
def close_windows():
    global running
    running = False
    clientsocket.close()
    s.close()
    chat_window.destroy()
    root.quit()


def login():
    username = username_entry.get()
    password = password_entry.get()

    if username == 'user' and password == 'password':
        chat_window.deiconify()
        root.withdraw()
    else:
        messagebox.showerror('Error', 'Invalid username or password')
def start_sending():
    global send_flag
    send_flag = True
    send_message()


root = Tk()
root.title("ChatApp")

login_frame = Frame(root)
login_frame.pack(pady=20)

Label(login_frame, text="用户名:").grid(row=0, column=0, padx=10, pady=5, sticky=E)
username_entry = Entry(login_frame)
username_entry.grid(row=0, column=1)

Label(login_frame, text="密码:").grid(row=1, column=0, padx=10, pady=5, sticky=E)
password_entry = Entry(login_frame, show="*")
password_entry.grid(row=1, column=1)

Button(login_frame, text="登录", command=login).grid(row=2, column=0, pady=10)
Button(login_frame, text="取消", command=close_windows).grid(row=2, column=1)

root.geometry('250x420-700+200')
root.protocol("WM_DELETE_WINDOW", close_windows)

chat_window = Toplevel()
chat_window.title('ChatApp')
chat_window.geometry('700x420-450+130')
chat_window.withdraw()

chat_frame = Frame(chat_window)
chat_frame.pack(pady=10)

scrollbar = Scrollbar(chat_frame)
scrollbar.pack(side=RIGHT, fill=Y)

chat_message = Text(chat_frame, width=97, height=25, state=DISABLED, padx=5, pady=5, yscrollcommand=scrollbar.set)
chat_message.pack()

scrollbar.config(command=chat_message.yview)

input_frame = Frame(chat_window)
input_frame.pack(pady=10)

input_message = Text(input_frame, width=50, height=2, padx=5, pady=5)
input_message.pack(side=LEFT)

send_button = Button(input_frame, text="发送", command=start_sending)
send_button.pack(side=LEFT, padx=10)
plot_button = Button(input_frame, text="画图", command=show_graph)
plot_button.pack(side=LEFT, padx=10)
sqylite_button = Button(input_frame, text="聊天记录",command=show_chat_records)
sqylite_button.pack(side=LEFT,padx=10)
chat_window.protocol("WM_DELETE_WINDOW", close_windows)

receive_thread = threading.Thread(target=receive_messages)
receive_thread.start()

root.mainloop()

# 客户端代码

from tkinter import *
from tkinter import messagebox
import threading
import socket
import matplotlib.pyplot as plt
import numpy as np
from matplotlib.backends.backend_tkagg import FigureCanvasTkAgg
from math import *
c = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
c.connect(('192.168.44.1', 1234))
send_flag = False
running = True


def receive_messages():
    global running
    while running:
        try:
            data = c.recv(1024).decode()
            if data:
                chat_message.configure(state=NORMAL)
                chat_message.insert(END,"服务器:"+data + '\n')
                chat_message.configure(state=DISABLED)
            if data.startswith("Function:y="):
                function_str=data[11:]
                try:
                    x = np.linspace(-10, 10, 100)  # 创建一个包含-10到10的100个数据点的数组
                    if "x" not in function_str:
                        raise ValueError("函数中未包含自变量 x")
                    y = eval(function_str)  # 计算函数在x值上的y值
                    dy_dx = np.gradient(y, x)  # 计算函数在x值上的一阶导数
                    # 绘制函数及其一阶导数的图像
                    plt.figure()
                    plt.subplot(2, 1, 1)
                    plt.plot(x, y)
                    plt.title('Function')
                    plt.xlabel('x')
                    plt.ylabel('y')
                    plt.subplot(2, 1, 2)
                    plt.plot(x, dy_dx)
                    plt.title('First Derivative')
                    plt.xlabel('x')
                    plt.ylabel("dy/dx")
                    plt.tight_layout()
                    plt.show()
                except Exception as e:
                    chat_message.insert(END, "计算出错:" + str(e) + '\n')
        except ConnectionError:
            break
# 将表达式转化为函数
def f(x, expression):
    func = np.vectorize(lambda x: eval(expression))
    return func(x)


# 求取函数的一阶导函数
def g(x, expression):
    return np.gradient(f(x, expression), x)
def show_graph():
    expression = input_message.get("1.0", END)
    expression = expression.strip()  # 去除空格和换行符
    if expression.startswith('y='):
        expression = expression[2:]

    if 'sin' in expression or 'cos' in expression:
        period = 4 * np.pi / abs(eval(expression.split('sin')[1] if 'sin' in expression else expression.split('cos')[1], {'x': 1}))
        x = np.linspace(-period / 2, period / 2, 100)  # 定义自变量的范围,共有 100 个点
    else:
        x = np.linspace(-10, 10, 50)  # 定义自变量的范围,共有 201 个点
        
    y = f(x, expression)  # 计算原函数的因变量的取值
    z = g(x, expression)  # 计算一阶导函数的因变量的取值

    # 绘制原函数和一阶导函数的图像
    fig, ax = plt.subplots(nrows=1, ncols=2, figsize=(10, 4))

    ax[0].plot(x, y)  # 绘制原函数图像
    ax[0].set_ylabel('y')  # 设置 y 轴标签
    ax[0].set_xlabel('x')  # 设置 x 轴标签
    ax[0].set_title('函数图像')  # 设置子图标题

    ax[1].plot(x, z)  # 绘制一阶导函数图像
    ax[1].set_ylabel('dy/dx')  # 设置 y 轴标签
    ax[1].set_xlabel('x')  # 设置 x 轴标签
    ax[1].set_title('一阶导数图像')  # 设置子图标题

    plt.tight_layout()  # 自动调整子图布局

    new_window = Toplevel()  # 创建新窗口
    new_window.title('图像')  # 设置窗口标题
    canvas = FigureCanvasTkAgg(fig, master=new_window)  # 绘制画布
    canvas.draw()
    canvas.get_tk_widget().pack(side=TOP, fill=BOTH, expand=1)  # 将画布添加到窗口中
    new_window.focus_set()  # 聚焦到新窗口
    new_window.grab_set()  # 捕获所有事件
    new_window.mainloop()  # 进入消息循环
def send_message():
    global send_flag
    if send_flag:
        message = input_message.get("1.0", END).strip()
        if message:
            input_message.delete("1.0", END)
            chat_message.configure(state=NORMAL)
            chat_message.insert(END,"我:"+message + '\n')
            chat_message.configure(state=DISABLED)
            c.send(message.encode())
            send_flag = False


def close_windows():
    global running
    running = False
    c.close()
    chat_window.destroy()
    root.quit()


def login():
    username = username_entry.get()
    password = password_entry.get()

    if username == 'user' and password == 'password':
        chat_window.deiconify()
        root.withdraw()
    else:
        messagebox.showerror('Error', 'Invalid username or password')

def start_sending():
    global send_flag
    send_flag = True
    send_message()
root = Tk()
root.title("ChatApp")

login_frame = Frame(root)
login_frame.pack(pady=20)

Label(login_frame, text="用户名:").grid(row=0, column=0, padx=10, pady=5, sticky=E)
username_entry = Entry(login_frame)
username_entry.grid(row=0, column=1)

Label(login_frame, text="密码:").grid(row=1, column=0, padx=10, pady=5, sticky=E)
password_entry = Entry(login_frame, show="*")
password_entry.grid(row=1, column=1)

Button(login_frame, text="登录", command=login).grid(row=2, column=0, pady=10)
Button(login_frame, text="取消", command=close_windows).grid(row=2, column=1)

root.geometry('250x420-700+200')
root.protocol("WM_DELETE_WINDOW", close_windows)

chat_window = Toplevel()
chat_window.title('ChatApp')
chat_window.geometry('700x420-450+130')
chat_window.withdraw()

chat_frame = Frame(chat_window)
chat_frame.pack(pady=10)

scrollbar = Scrollbar(chat_frame)
scrollbar.pack(side=RIGHT, fill=Y)

chat_message = Text(chat_frame, width=97, height=25, state=DISABLED, padx=5, pady=5, yscrollcommand=scrollbar.set)
chat_message.pack()

scrollbar.config(command=chat_message.yview)

input_frame = Frame(chat_window)
input_frame.pack(pady=10)

input_message = Text(input_frame, width=50, height=2, padx=5, pady=5)
input_message.pack(side=LEFT)

send_button = Button(input_frame, text="发送", command=start_sending)
send_button.pack(side=LEFT, padx=10)
plot_button = Button(input_frame, text="画图", command=show_graph)
plot_button.pack(side=LEFT, padx=10)
sqylite_button = Button(input_frame, text="聊天记录")
sqylite_button.pack(side=LEFT,padx=10)
chat_window.protocol("WM_DELETE_WINDOW", close_windows)

receive_thread = threading.Thread(target=receive_messages)
receive_thread.start()

root.mainloop()



本项目指在设计一个基于python GUI编程,matplotlib画图,MySQL数据库操作以及网络通信图形界面的程序。源码如上,欢迎指正!

Python有很多聊天软件开发框架和库可以使用。其中一个比较常用的是基于Python的Socket编程来实现聊天功能。你可以使用Python的socket库来创建一个服务器和客户端,通过网络连接来进行聊天。 示例代码如下: 服务器端: ```python import socket def start_server(): host = 'localhost' port = 8000 # 创建一个socket对象 server_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM) server_socket.bind((host, port)) # 监听连接 server_socket.listen(1) print('等待客户端连接...') # 接受客户端连接 client_socket, addr = server_socket.accept() print('与客户端连接成功:', addr) # 接收并发送消息 while True: data = client_socket.recv(1024).decode() print('客户端:', data) message = input('服务器:') client_socket.send(message.encode()) if message == 'quit': break # 关闭连接 client_socket.close() server_socket.close() start_server() ``` 客户端: ```python import socket def start_client(): host = 'localhost' port = 8000 # 创建一个socket对象 client_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM) # 连接服务器 client_socket.connect((host, port)) print('与服务器连接成功') # 发送和接收消息 while True: message = input('客户端:') client_socket.send(message.encode()) if message == 'quit': break data = client_socket.recv(1024).decode() print('服务器:', data) # 关闭连接 client_socket.close() start_client() ``` 你可以运行以上代码来创建一个简单的聊天服务器和客户端,通过在终端输入消息进行聊天。请注意,此示例只是简单地发送和接收消息,并没有处理更多复杂的逻辑,你可以根据自己的需求进行扩展和修改。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值