python实现的聊天室(二)

1、前言

我在python实现的聊天室(一)一文中实现了一个没有界面的聊天室,所有操作都在CMD命令行下进行,用户体验比较差。所以在这一篇文章中,主要实现一个有界面的聊天室。

2、需求分析

我们要实现的分为两部分:

服务器:负责与用户建立 Socket 连接,并将某个用户发送的消息广播到所有在线的用户。显示用户进入/退出聊天室信息。

客户端:可以输入聊天的内容并发送,同时可以显示其他用户的消息记录。

3、服务端实现

# -*- coding: gbk -*-

from PyQt4.QtGui import *

from PyQt4.QtCore import *

import sys

from PyQt4.QtNetwork import *

import locale

#QTextCodec.setCodecForTr(QTextCodec.codecForName("utf8"))

class TcpClientSocket(QTcpSocket):

def __init__(self,parent=None):

super(TcpClientSocket,self).__init__(parent)

self.connect(self,SIGNAL("readyRead()"),self.dataReceive)

self.connect(self,SIGNAL("disconnected()"),self.slotDisconnected)

self.length = 0

self.msglist = QByteArray()

def dataReceive(self):

while self.bytesAvailable() > 0:

length = self.bytesAvailable()

msg = self.read(length)

self.emit(SIGNAL("updateClients(QString,int)"),msg,length)

def slotDisconnected(self):

pass

class Server(QTcpServer):

def __init__(self,parent=None,port=0):

super(Server,self).__init__(parent)

self.listen(QHostAddress.Any,port)

self.tcpClientSocketList = []

def incomingConnection(self,socketDescriptor):

tcpClientSocket = TcpClientSocket(self)

self.connect(tcpClientSocket,SIGNAL("updateClients(QString,int)"),self.updateClients)

self.connect(tcpClientSocket,SIGNAL("disconnetcted(int)"),self.slotDisconnected)

tcpClientSocket.setSocketDescriptor(socketDescriptor)

self.tcpClientSocketList.append(tcpClientSocket)

def updateClients(self,msg,length):

self.emit(SIGNAL("updateServer(QString,int)"),msg,length)

for i in xrange(len(self.tcpClientSocketList)):

item = self.tcpClientSocketList[i]

length_msg = item.writeData(msg)

#length_msg = item.writeData(msg.toUtf8())

#if length_msg != msg.toUtf8().length():

# continue

def slotDisconnected(self,descriptor):

for i in xrange(len(self.tcpClientSocketList)):

item = self.tcpClientSocketList[i]

if item.socketDescriptor() == descriptor:

self.tcpClientSocketList.remove[i]

return

return

class TcpServer(QDialog):

def __init__(self,parent=None,f=None):

super(TcpServer,self).__init__(parent)

self.setWindowTitle("服务端")

vbMain = QVBoxLayout(self)

self.ListWidgetContent = QListWidget(self)

vbMain.addWidget(self.ListWidgetContent)

hb = QHBoxLayout()

LabelPort = QLabel(self)

LabelPort.setText(self.tr("Port:"))

hb.addWidget(LabelPort)

LineEditPort = QLineEdit(self)

hb.addWidget(LineEditPort)

vbMain.addLayout(hb)

self.PushButtonCreate = QPushButton(self)

self.PushButtonCreate.setText(self.tr("创建聊天室"))

vbMain.addWidget(self.PushButtonCreate)

self.connect(self.PushButtonCreate,SIGNAL("clicked()"),self.slotCreateServer)

self.port = 8010

LineEditPort.setText(QString.number(self.port))

def slotCreateServer(self):

server = Server(self,self.port)

self.connect(server,SIGNAL("updateServer(QString,int)"),self.updateServer)

self.PushButtonCreate.setEnabled(False)

def updateServer(self,msg,length):

#self.ListWidgetContent.addItem(msg.fromUtf8(msg))

self.ListWidgetContent.addItem(msg)

if __name__ == '__main__':

app=QApplication(sys.argv)

mycode = locale.getpreferredencoding()

code = QTextCodec.codecForName(mycode)

QTextCodec.setCodecForLocale(code)

QTextCodec.setCodecForTr(code)

QTextCodec.setCodecForCStrings(code)

dialog=TcpServer()

dialog.show()

app.exec_()

4、客户端实现

# -*- coding: gbk -*-

from PyQt4.QtGui import *

from PyQt4.QtCore import *

import sys

from PyQt4.QtNetwork import *

import locale

#QTextCodec.setCodecForTr(QTextCodec.codecForName("utf8"))

class TcpClient(QDialog):

def __init__(self,parent=None):

super(TcpClient,self).__init__(parent)

self.setWindowTitle(self.tr("客户端"))

self.status = False

self.serverIP = QHostAddress()

self.port = 8010

self.msglist = QByteArray()

vbMain = QVBoxLayout(self)

self.ListWidgetContent = QListWidget(self)

vbMain.addWidget(self.ListWidgetContent)

hb = QHBoxLayout()

self.LineEditMessage = QLineEdit(self)

hb.addWidget(self.LineEditMessage)

self.PushButtonSend = QPushButton(self)

self.PushButtonSend.setText(self.tr("发送"))

self.PushButtonSend.setEnabled(False)

hb.addWidget(self.PushButtonSend)

self.connect(self.PushButtonSend,SIGNAL("clicked()"),self.slotSend)

hb1 = QHBoxLayout()

LabelName = QLabel(self)

LabelName.setText(self.tr("用户名:"))

self.LineEditUser = QLineEdit(self)

hb1.addWidget(LabelName)

hb1.addWidget(self.LineEditUser)

hb2 = QHBoxLayout()

LabelServerIP = QLabel(self)

LabelServerIP.setText(self.tr("服务器地址:"))

self.LineEditIP = QLineEdit(self)

hb2.addWidget(LabelServerIP)

hb2.addWidget(self.LineEditIP)

hb3 = QHBoxLayout()

LabelPort = QLabel(self)

LabelPort.setText(self.tr("端口:"))

self.LineEditPort = QLineEdit(self)

hb3.addWidget(LabelPort)

hb3.addWidget(self.LineEditPort)

vbMain.addLayout(hb)

vbMain.addLayout(hb1)

vbMain.addLayout(hb2)

vbMain.addLayout(hb3)

self.PushButtonLeave = QPushButton(self)

self.PushButtonLeave.setText(self.tr("进入聊天室"))

vbMain.addWidget(self.PushButtonLeave)

self.connect(self.PushButtonLeave,SIGNAL("clicked()"),self.slotEnter)

def slotSend(self):

msg = self.userName + ":" + self.LineEditMessage.text(

#length = self.tcpSocket.writeData(msg.toUtf8())

length = self.tcpSocket.writeData(msg)

self.LineEditMessage.clear()

#if length != msg.toUtf8().length():

# return

def slotEnter(self):

if not self.status:

ip = self.LineEditIP.text()

if not self.serverIP.setAddress(ip):

QMessageBox.information(self,self.tr("error"),self.tr("server ip address error!"))

return

if self.LineEditUser.text() == "":

QMessageBox.information(self,self.tr("error"),self.tr("User Name error!"))

return

self.userName = self.LineEditUser.text()

self.tcpSocket = QTcpSocket(self)

self.connect(self.tcpSocket,SIGNAL("connected()"),self.slotConnected)

self.connect(self.tcpSocket,SIGNAL("disconnected()"),self.slotDisconnected)

self.connect(self.tcpSocket,SIGNAL("readyRead()"),self.dataReceived)

self.tcpSocket.connectToHost(self.serverIP.toString(),8010)

self.status = True

else:

msg = self.userName + ":" + self.tr("离开聊天室")

length = self.tcpSocket.writeData(msg)

#length = self.tcpSocket.writeData(msg.toUtf8())

#if length != msg.toUtf8().length():

# return

self.tcpSocket.disconnectFromHost()

self.status = False

def slotConnected(self):

self.PushButtonSend.setEnabled(True)

self.PushButtonLeave.setText(self.tr("离开聊天室"))

msg = self.userName + ":" + self.tr("进入聊天室")

#length = self.tcpSocket.writeData(msg.toUtf8())

length = self.tcpSocket.writeData(msg)

#if length != msg.toUtf8().length():

# return

def slotDisconnected(self):

self.PushButtonSend.setEnabled(False)

self.PushButtonLeave.setText(self.tr("进入聊天室"))

def dataReceived(self):

while self.tcpSocket.bytesAvailable() > 0:

length = self.tcpSocket.bytesAvailable()

msg = QString(self.tcpSocket.read(length))

#msg = msg.fromUtf8(msg)

#self.ListWidgetContent.addItem(msg.fromUtf8(msg))

self.ListWidgetContent.addItem(msg)

if __name__ == '__main__':

app=QApplication(sys.argv)

mycode = locale.getpreferredencoding()

code = QTextCodec.codecForName(mycode)

QTextCodec.setCodecForLocale(code)

QTextCodec.setCodecForTr(code)

QTextCodec.setCodecForCStrings(code)

dialog=TcpClient()

dialog.show()

app.exec_()

5、运行效果

运行时先启动服务端,再运行客户端。服务器启动后创建聊天室。客户端运行后,输入昵称、服务器的IP及port信息,进入聊天室。此时服务端会提示用户进入聊天室。当客户端关闭,表明该用户退出聊天室,服务器会转发该用户退出消息到各个客户端。

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-TLWfRAnb-1593526750899)(http://odsh9s4s2.bkt.clouddn.com/mypyqtchatserver.png)]

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-XLahNRDt-1593526750901)(http://odsh9s4s2.bkt.clouddn.com/mypyqtchatclientA.png)]

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-xB06qmLF-1593526750903)(http://odsh9s4s2.bkt.clouddn.com/mypyqtchatclientB.png)]

6、参考链接

因为代码中用到了汉字,所以涉及到编码问题。希望该链接能帮助到你。

http://blog.csdn.net/uselym/article/details/51867056

526750901)]

[外链图片转存中…(img-xB06qmLF-1593526750903)]

6、参考链接

基于python的网络聊天室论文_基于python的聊天室(2),实现,二相关推荐

  1. java web聊天室论文_基于javaweb聊天室.doc

    基于javaweb聊天室.doc 南嗦岌凌*4 文(设计) 本科生毕业论 题 目:基于Java网页版聊天室的设计与实现 姓名:陈义旺 学院:理学院 专业:信息与计算科学 班级:信科092 学号: 指导 ...

  2. java web聊天室论文_基于Java网页版聊天室的设计与实现毕业论文含开报告及文献综述.doc...

    基于Java网页版聊天室的设计与实现毕业论文含开报告及文献综述 本科生毕业论文(设计) 题 目: 基于Java网页版聊天室的设计与实现 姓 名:学 院: 理学院 专 业: 信息与计算科学 班 级: 信 ...

  3. java web聊天室论文_基于java网页版聊天室的设计与实现毕业论文含开题报告及文献综述.doc...

    基于java网页版聊天室的设计与实现毕业论文含开题报告及文献综述.doc 还剩 52页未读, 继续阅读 下载文档到电脑,马上远离加班熬夜! 亲,很抱歉,此页已超出免费预览范围啦! 如果喜欢就下载吧,价 ...

  4. java web聊天室论文_基于Java网页版聊天室的设计与实现毕业论文含开题报告及文献综述(样例3)...

    <基于Java网页版聊天室的设计与实现毕业论文含开题报告及文献综述.doc>由会员分享,可免费在线阅读全文,更多与<基于Java网页版聊天室的设计与实现毕业论文含开题报告及文献综述& ...

  5. python关于二手房的课程论文_基于python爬取链家二手房信息代码示例

    基本环境配置 python 3.6 pycharm requests parsel time 相关模块pip安装即可 确定目标网页数据 哦豁,这个价格..................看到都觉得脑阔 ...

  6. 基于python的股票程序化交易论文_基于Python工具的股票量化投资策略研究

    2019 年第 07 期 20 世 纪 80 年代, 一 些 投 资 者 开 始 利用 计 算 机 研究金 融 数据 , 并 初显 成 效 . 20 世 纪 末 , 投 资 者 把 计 算 机 技术 ...

  7. python设计贪吃蛇游戏论文_用Python写一个贪吃蛇AI,让程序自己玩游戏

    前言 这两天在网上看到一张让人涨姿势的图片,图片中展示的是贪吃蛇游戏, 估计大部分人都玩过.但如果仅仅是贪吃蛇游戏,那么它就没有什么让人涨姿势的地方了. 问题的关键在于,图片中的贪吃蛇真的很贪吃XD, ...

  8. python如何爬取sci论文_利用python爬取并翻译GEO数据库

    GEO数据库是NCBI创建并维护的基因表达数据库,始于2000年,收录了世界各国研究机构提交的高通量基因表达数据,现芯片集数据量高达12万以上.想要从这里面挖掘(bai piao)数据,发个sci提前 ...

  9. python的网络编程学什么_【Python学习】网络编程

    1 # 1.发get请求 2 import requests 3 url = 'http://api.nnzhp.cn/api/user/stu_info' 4 data = {'stu_name': ...

  10. python关于二手房的课程论文_用Python对二手房信息数据清洗及简单分析

    另外两份作业: 这几天看到社群大佬同学们发的作业,对本人有所启发,于是找来前段时间爬取的某二手房网站房源信息,进行简单的操作. 根据数据分析的基本步骤 一.提出问题 根据爬取的网站信息,额想不出有什么 ...

最新文章

  1. 杀毒软件全免费遭厂家“抵制”
  2. vue mint-ui 弹出框
  3. 【Spark】开发Spark选择Java还是Scala?
  4. 安装cleanmymac软件提示已损坏无法打开,如何解决?
  5. 10815 - Andy's First Dictionary
  6. DEV控件:gridControl常用属性设置
  7. vsftp账号_Linux下vsftp的重新安装和配置虚拟用户
  8. go Mutex (互斥锁)和RWMutex(读写锁)
  9. mysql 1045 - Access denied for user 'root'@'*.*.*.*' (using password YES)
  10. 《C#图解教程》读书笔记之五:委托和事件
  11. C语言哈希表uthash的使用方法详解(附下载链接)
  12. 使用 Beyond Compare 和版本控制系统
  13. 判断一个正整数是素数还是合数
  14. 站群服务器用SS5 SOCKS5 配置多IP/多端口高性能代理服务器(16G内存主机支持超过100万并发S5代理)
  15. DM数据库全面调优指南之Linux操作系统
  16. c#对使用US7ASCII的oracle存取中文的问题
  17. 计算机主机和外设的接口是,外设接口
  18. cisco服务器设置步骤_设置您自己的邮件服务器的10个步骤
  19. 从零基础到精通的Python学习路线(附教程)
  20. 反骨之Java是如何解决并发中的可见性问题的

热门文章

  1. 银河帝国----基地前奏
  2. 数据挖掘常用算法优缺点分析
  3. LSD_SLAM编译运行
  4. python小程序之天天向上
  5. 化云为雨,华为云为什么要深入经济的“毛细血管”?
  6. 正确的序号及标点使用格式(参考文)
  7. 53、backtrader的一些基本概念---如何用backtrader画图?
  8. 钉钉审批流API接口
  9. 26岁考计算机研究生,26岁考研究生好还是考公务员好?总结得太精辟了
  10. 利用scrapy爬取新浪体育新闻的小例子