利用 Python 结合 UI 来模拟实现多人聊天

news2025/1/19 8:31:12

一、界面功能展示

1、设置一个通信  用户1

 2、设置通信  用户2

 3、进入聊天功能界面

 

 4、发送信息来实现实时通信 

二、代码实现

1、服务器端

(服务器需要能够与客户机进行直接通信,客户机之间不需要能够通信)

      服务器需要配置监听的IP = '0.0.0.0' 表示所有 port= '端口随意但是要与客户端配置的端口相同'

import socket
import threading

def handle_client(client_socket, clients):
    while True:
        try:
            data = client_socket.recv(1024)
            if not data:
                break
            for client in clients:
                if client != client_socket:
                    client.send(data)
        except:
            break
    client_socket.close()

def main():
    host = '0.0.0.0'
    port = 1996

    server = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    server.bind((host, port))
    server.listen(5)

    print(f"[*] Listening on {host}:{port}")

    clients = []

    while True:
        client_socket, addr = server.accept()
        print(f"[*] Accepted connection from {addr[0]}:{addr[1]}")
        clients.append(client_socket)
        client_handler = threading.Thread(target=handle_client, args=(client_socket, clients))
        client_handler.start()

if __name__ == "__main__":
    main()

2、客户端

①localhost是在本地调试使用,如果服务器是其他IP,需要进行配置,

②端口与服务器需要对应

import socket
import threading
import sys
from PyQt5.QtWidgets import QApplication, QMainWindow, QTextBrowser, QLineEdit, QVBoxLayout, QWidget, QPushButton, QInputDialog, QDesktopWidget
from PyQt5.QtCore import Qt

class ChatClient(QMainWindow):
    def __init__(self):
        super().__init__()
        self.username = None  # 初始化用户名为None
        self.init_ui()

    def init_ui(self):
        self.chat_window = QTextBrowser()
        self.input_field = QLineEdit()
        self.send_button = QPushButton("Send")
        self.send_button.clicked.connect(self.send_message)

        self.exit_button = QPushButton("Exit")
        self.exit_button.clicked.connect(self.exit)

        layout = QVBoxLayout()
        layout.addWidget(self.chat_window)
        layout.addWidget(self.input_field)
        layout.addWidget(self.send_button)
        layout.addWidget(self.exit_button)

        central_widget = QWidget()
        central_widget.setLayout(layout)
        self.setCentralWidget(central_widget)

        self.setWindowTitle("Chat Client")
        self.setGeometry(0, 0, 400, 400)  # 初始位置和大小设置为0, 0, 400, 400

        self.center_window()  # 调用居中方法

        self.client_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
        self.client_socket.connect(("localhost", 9999))  

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

        # 监听回车键事件
        self.input_field.returnPressed.connect(self.send_message)

        # 弹出对话框设置用户名
        self.set_username()

    def center_window(self):
        # 获取屏幕尺寸
        screen_geometry = QDesktopWidget().screenGeometry()
        window_geometry = self.geometry()
        # 计算居中位置
        x = (screen_geometry.width() - window_geometry.width()) // 2
        y = (screen_geometry.height() - window_geometry.height()) // 2
        self.move(x, y)  # 将窗口移动到居中位置

    def set_username(self):
        self.username, ok = self.get_text_input("Set Username", "Enter your username:")
        if not ok:
            self.close()
        else:
            self.setWindowTitle(f"Chat Client - {self.username}")

    def get_text_input(self, title, prompt):
        text, ok = QInputDialog.getText(self, title, prompt)
        return (text.strip(), ok)

    def receive_messages(self):
        while True:
            try:
                message = self.client_socket.recv(1024).decode("utf-8")
                if message == "exit":
                    break
                self.chat_window.append(message)
            except:
                break

    def send_message(self):
        message = self.input_field.text()
        if message:
            full_message = f"{self.username}: {message}"
            self.client_socket.send(full_message.encode("utf-8"))
            self.input_field.clear()

    def exit(self):
        self.client_socket.send("exit".encode("utf-8"))
        self.client_socket.close()
        sys.exit()

if __name__ == "__main__":
    app = QApplication(sys.argv)
    client = ChatClient()
    client.show()
    sys.exit(app.exec_())

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/829077.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

改进粒子群算法优化BP神经网络---回归+分类两种案例

今天采用改进的粒子群算法(LPSO)优化算法优化BP神经网络。本文选用的LPSO算法是之前作者写过的一篇文章:基于改进莱维飞行和混沌映射(10种混沌映射随意切换)的粒子群优化算法,附matlab代码 文章一次性讲解两种案例,回归…

Mr. Cappuccino的第58杯咖啡——MacOS配置Maven和Java环境

MacOS配置Maven和Java环境 查看Mac使用的是哪个shell下载并准备Maven下载Maven配置前准备 下载并安装JDK下载JDK安装JDK 配置Maven和Java环境添加配置加载配置 验证环境 查看Mac使用的是哪个shell echo $SHELL如果使用的是bash,则使用以下命令 open ~/.bash_profi…

Java课题笔记~ MyBatis接口开发(代理开发)

使用XML文件进行开发,在调用SqlSession进行操作时,需要指定MyBatis映射文件中的方法,这种调用方式过于烦琐。为解决此问题,MyBatis提供了接口开发的方式。 接口开发的目的: 解决原生方式中的硬编码 简化后期执行SQL …

PHP语言基础知识(超详细)

文章目录 前言第一章 PHP语言学习介绍 1.1 PHP部署安装环境1.2 PHP代码工具选择 第二章 PHP代码基本语法 2.1 PHP函数知识介绍2.2 PHP常量变量介绍 2.2.1 PHP变量知识:2.2.2 PHP常量知识: 2.3 PHP注释信息介绍2.4 PHP数据类型介绍 2.4.1 整形数据类型2.4…

【elementui】解决el-select组件失去焦点blur事件每次获取的是上一次选中值的问题

目录 【问题描述】 【问题摘要】 【分析问题】 【完整Test代码】 【封装自定义指令】 ↑↑↑↑↑↑↑↑↑↑↑↑ 不想看解决问题过程的可点击上方【封装自定义指令】目录直接跳转获取结果即可~~~ 【问题描述】 一位朋友遇到这么一个开发场景:在表格里面嵌入el-…

Packet Tracer - 配置初始交换机设置

Packet Tracer - 配置初始交换机设置 拓扑 目标 第 1 部分:检验默认交换机配置 第 2 部分:配置基本交换机配置 第 3 部分:配置 MOTD 标语 第 4 部分:将配置文件保存到 NVRAM 第 5 部分:配置 S2 拓扑图 背景信息…

【Mybatis】XML映射文件

目录 11.3XML映射文件 1.select 2.insert、update、delete 3.Sql 4.parameters(参数) 5.resultMap 6.resultMap 使用示例 (1)在先前创建的数据库stu中创建表student 2,并插入若干条数据,代码如下: (2)创建工程mybatis_ResultMap_demo。 (…

Qt项目---简单的计算器

在这篇技术博客中,我们将介绍如何使用Qt框架实现一个简单的计算器应用。我们将使用C编程语言和Qt的图形用户界面库来开发这个应用,并展示如何实现基本的算术操作。 项目设置 首先,我们需要在Qt Creator中创建一个新的Qt Widgets应用程序项目…

7.物联网操作系统互斥信号量

优先级翻转问题 优先级翻转功能需求 优先级翻转功能实现 一。实验:优先级翻转问题 1.优先级翻转的解释 (1)有三个任务,一个任务L优先级最低,一个任务M优先级为中间,一个任务H优先级为最高。 &#xff08…

SpringBoot集成企业微信群聊机器人消息

目录 参考文档概述一、功能作用二、应用场景三、 群机器人发送限制四、创建机器人1、添加2、群机器人Webhook地址 五、发送消息1、文本 text请求体 图文连接 news 参考文档 官方文档 企业微信群机器人应用 概述 现在很多企业都在使用企业微信进行工作交流,自从企…

静态路由下一跳地址怎么确定(静态路由配置及讲解)

一、用到的所有命令及功能 ①ip route-static 到达网络地址 子网掩码 下一跳 // 配置静态路由下一跳指的是和当前网络直接连接的路由器的接口地址非直连网段必须全部做路由路径是手工指定的,在大规模网络上不能用,效率低,路径是固定的稳定的…

寻找旋转排序数组中的最小值——力扣153

文章目录 题目描述解法 二分法 题目描述 解法 二分法 int findMin(vector<int>& nums){int l0, rnums.size()-1;while(l<r){int mid (lr)/2;if(nums[mid]<nums[r]) rmid;else lmid1;}return nums[l];}

基于freeRTOS的垃圾桶(cubeMX)

前言&#xff1a;最近学习了freertos的任务、队列、互斥量、任务标志位等理论知识&#xff0c;看着都会就怕一练就废&#xff0c;于是打算做些项目巩固一下&#xff0c;加深一下对freertos知识的理解。 一、项目介绍 项目简单需求&#xff1a; 检测靠近时&#xff0c;垃圾桶自…

APUE学习62章终端(二): stty命令特殊字符终端标志

1. stty命令 stty命令的英文解释: 很明显stty有一个-F参数 所以准确的说: stty命令是设置当前终端驱动程序(也有可能直接配置了硬件&#xff0c;这点目前不清楚)的属性&#xff0c;使当前终端的驱动程序能够使能/去使能一些特殊字符的识别与处理等等 2. stty命令的结构 3. 终端…

Python web实战之 Django 的 ORM 框架详解

本文关键词&#xff1a;Python、Django、ORM。 概要 在 Python Web 开发中&#xff0c;ORM&#xff08;Object-Relational Mapping&#xff0c;对象关系映射&#xff09;是一个非常重要的概念。ORM 框架可以让我们不用编写 SQL 语句&#xff0c;就能够使用对象的方式来操作数据…

总结946

6:40起床 7&#xff1a;15~8:00早读&#xff0c;07年tex1,2 8:10~10:12 880第二章选填&#xff0c;题目有些综合&#xff0c;错的有些多呀&#xff0c;不要紧&#xff0c;拿下它&#xff0c;就有进步了。 10:28~11:27重做强化18讲6道题 12&#xff1a;10~2:15吃饭睡觉&…

MySQL 三大日志日志:undo log、redo log、binlog

目录 一条SQL的执行流程 为什么需要 undo log&#xff1f; undo log 是如何刷盘&#xff08;持久化到磁盘&#xff09;的&#xff1f; 为什么需要 Buffer Pool&#xff1f; Buffer Pool 缓存什么&#xff1f; Undo 页是记录什么&#xff1f; 查询一条记录&#xff0c;就只需…

代码随想录算法训练营第三十二天 | Leetcode随机抽题检测

Leetcode随机抽题检测 46 全排列未看解答自己编写的青春版重点题解的代码日后复习重新编写 78 子集未看解答自己编写的青春版重点题解的代码日后复习重新编写 17 电话号码的字母组合未看解答自己编写的青春版重点题解的代码日后复习重新编写 39 组合总和未看解答自己编写的青春…

SpringBoot项目增加logback日志文件

一、简介 在开发和调试过程中&#xff0c;日志是一项非常重要的工具。它不仅可以帮助我们快速定位和解决问题&#xff0c;还可以记录和监控系统的运行状态。Spring Boot默认提供了一套简单易用且功能强大的日志框架logback&#xff0c;本文将介绍如何在Spring Boot项目中配置和…

使用AIGC工具提升安全工作效率

新钛云服已累计为您分享760篇技术干货 在日常工作中&#xff0c;安全人员可能会涉及各种各样的安全任务&#xff0c;包括但不限于&#xff1a; 开发某些安全工具的插件&#xff0c;满足自己特定的安全需求&#xff1b;自定义github搜索工具&#xff0c;快速查找所需的安全资料、…