使用PyQt4和twisted写的局域网聊天室(3)
qt4guiServer.py:
# -*- coding: utf-8 -*-
import sys
from PyQt4 import QtCore, QtGui
class ServerGui(QtGui.QDialog):
def __init__(self, parent = None):
super(ServerGui, self).__init__()
self.setGeometry(400, 400, 700, 400) #窗口位置的x和y坐标,窗口的宽度和高度
self.setWindowTitle('服务端'.decode('utf-8')) #中文显示 .decode('utf-8')
#self.resize(646,390) #重新调整窗口的宽度和高度
self.leftLayout()
self.rightLayout()
mainLayout = QtGui.QHBoxLayout() #水平布局
mainLayout.addWidget(self.leftGroupBox,1) #注意这里添加的GroupBox
mainLayout.addWidget(self.rightGroupBox,2) #stretch表示伸展系数
self.setLayout(mainLayout)
def leftLayout(self):
self.leftGroupBox = QtGui.QGroupBox("Start server")
self.leftGroupBox.setStyleSheet("background-color: rgb(200, 200, 255);") #改变程序的界面颜色
personLabel = QtGui.QLabel("users:")
self.personBrowser = QtGui.QTextBrowser() #仅能浏览
portLabel = QtGui.QLabel("port:") #portLabel.setStyleSheet("""border-color: rgb(0, 85, 255); color: rgb(255, 85, 0);""")
self.portEdit = QtGui.QLineEdit("8765") #定义端口
self.startButton = QtGui.QPushButton("&Start")
layout = QtGui.QGridLayout()
layout.addWidget(personLabel,0,0)
layout.addWidget(self.personBrowser,0,1) #显示获取的聊天客户
layout.addWidget(portLabel,1,0)
layout.addWidget(self.portEdit,1,1)
layout.addWidget(self.startButton,2,0)
layout.setColumnStretch(1, 10)
self.leftGroupBox.setLayout(layout)
def rightLayout(self):
self.rightGroupBox = QtGui.QGroupBox("Message Information")
self.messageBrowser = QtGui.QTextBrowser()
layout = QtGui.QVBoxLayout()
layout.addWidget(self.messageBrowser)
self.rightGroupBox.setLayout(layout)
def retranslateUi(self):
# self.personBrowser.setText(QtGui.QApplication.translate("Form", " 发送", None, QtGui.QApplication.UnicodeUTF8))
# self.portEdit.setText(QtGui.QApplication.translate("Form", "关闭", None, QtGui.QApplication.UnicodeUTF8))
# self.startButton.setText(QtGui.QApplication.translate("MainWindow", "Start", None, QtGui.QApplication.UnicodeUTF8))
# self.messageBrowser.setText(QtGui.QApplication.translate("Form", "关闭", None, QtGui.QApplication.UnicodeUTF8))
pass
if __name__ == "__main__":
app = QtGui.QApplication(sys.argv)
cd = ServerGui()
cd.show()
sys.exit(app.exec_())
server.py:
# -*- coding: utf-8 -*-
import sys,time
from twisted.internet.protocol import Factory, Protocol
from PyQt4 import QtCore, QtGui
import qt4reactor
from qt4guiServer import *
reload(sys)
sys.setdefaultencoding( "utf-8" )
app=QtGui.QApplication(['Server'])
GUI=ServerGui()
GUI.show()
reactor=qt4reactor.install()
MsgRcv = ""
MsgSnd = ""
class User():
def __init__(self):
self.userList = [] # 用户列表
def addUser(self,userName,password,transport,statusMessage):
self.userList.append((userName,password,transport,statusMessage)) ## userList是否添加statusMessage?
GUI.messageBrowser.append(userName+" 进入房间。".decode('utf-8')+"\n")
GUI.personBrowser.append(userName+":"+statusMessage)
def removeUser(self,userName):
GUI.personBrowser.clear()
temp=[]
for i in self.userList:
if i[0] != userName:
temp.append(i)
GUI.personBrowser.append(i[0]+" "+i[3])
self.userList=temp
GUI.messageBrowser.append(userName+" 离开房间。".decode('utf-8')+"\n")
def names(self):
names = []
for i in self.userList:
names.append(i[0])
return names
users = User() #创建类的实例
class Echo(Protocol): #定义协议
def connectionMade(self):
GUI.messageBrowser.append("connected...")
self.factory.numProtocols = self.factory.numProtocols + 1 #协议连接数
self.userName = "un_named" #未具名用户
self.flag = 1 ## 用户标记,为0时用户已存在?是否有用?
def connectionLost(self, reason):
self.factory.numProtocols = self.factory.numProtocols - 1
GUI.messageBrowser.append(self.userName+" lost connection...") # reason.getErrorMessage()
if self.flag != 0:
users.removeUser(self.userName)
MsgSnd = "LOGOUT" + ">>:" + self.userName
for i in users.userList:
i[2].write(MsgSnd) #向其它用户发送断开连接,i[2]为tranport
#更新列表
def dataReceived(self, data):
self.flag = 1
MsgRcv = data.split("<<:")
if MsgRcv[0] =="LOGIN":
userName = MsgRcv[1]
self.userName = userName # 注意此行代码
password = MsgRcv[2] ## 暂时还未添加用户密码 ?
statusMessage = MsgRcv[3]
if userName in users.names(): # 用户已存在
self.flag = 0
content = " 已存在"
MsgSnd = "USEREXISTED" + ">>:" + userName + ">>:" + content
self.transport.write(MsgSnd)
content = content.decode('utf-8')
GUI.messageBrowser.append(userName + content+ ",请修改用户名称。".decode('utf-8')+"\n")
else: #新用户接收老用户信息,老用户接收新用户信息
MsgSnd = "USERLIST"
for i in users.userList:
MsgSnd = "USERLIST" + ">>:" +i[0] + ">>:"+ i[3]+">>>>" #userName statusMessage
if MsgSnd != "USERLIST": #首次老用户可能为空
self.transport.write(MsgSnd) #老用户信息发送给新用户
for i in users.userList:
MsgSnd = "NEWUSER" + ">>:" + userName + ">>:" + statusMessage
i[2].write(MsgSnd)
if userName != "un_named":
users.addUser(userName,password,self.transport,statusMessage)
elif MsgRcv[0] =="COMMONCHAT":
userName = MsgRcv[1]
content = MsgRcv[2]
MsgSnd = "COMMONCHAT" + ">>:"+ userName + ">>:"+ content
for i in users.userList:
i[2].write(MsgSnd)
nowtime = time.strftime(' %H:%M:%S ')
content = content.decode("utf-8")
GUI.messageBrowser.append(userName + nowtime + ">> "+content+"\n")
elif MsgRcv[0] == "NEWPRIVATE":
userName = MsgRcv[1]
recipient = MsgRcv[2]
MsgSnd = "NEWPRIVATE" + ">>:" + recipient + ">>:"+ userName
for i in users.userList:
if i[0] == recipient:
i[2].write(MsgSnd)
break
elif MsgRcv[0] =="PRIVATECHAT":
userName = MsgRcv[1]
recipient = MsgRcv[2]
content = MsgRcv[3]
MsgSnd = "PRIVATECHAT" + ">>:" + recipient + ">>:"+ userName +">>:"+ content
for i in users.userList:
if i[0] == recipient:
i[2].write(MsgSnd)
break
nowtime = time.strftime(' %H:%M:%S ')
GUI.messageBrowser.append(userName +"->" +recipient + nowtime + ">> "+content.decode('utf-8')+"\n")
class EchoFactory(Factory):
protocol = Echo #定义协议Echo
def __init__(self):
self.numProtocols=0
def startService():
GUI.messageBrowser.append("Listening..."+"\n")
reactor.listenTCP(int(GUI.portEdit.text().__str__().__str__()), EchoFactory())
GUI.portEdit.setEnabled(False)
GUI.startButton.setEnabled(False)
QtCore.QObject.connect(GUI.startButton,QtCore.SIGNAL("clicked()"),startService)
reactor.runReturn()
sys.exit(app.exec_())