qt4guiClient.py:
# -*- coding: utf-8 -*-
import os,sys
from PyQt4 import QtCore, QtGui
reload(sys)
sys.setdefaultencoding('utf-8')
from qt4guiPTalk import *
class ClientGui(QtGui.QMainWindow):
def __init__(self,parent=None):
super(ClientGui, self).__init__()
self.setGeometry(400, 400, 700, 400) #窗口位置的x和y坐标,窗口的宽度和高度
self.setWindowTitle('客户端'.decode('utf-8')) #中文显示 .decode('utf-8')
self.centerWidget= QtGui.QWidget()
self.setCentralWidget(self.centerWidget)
self.leftWidget = LeftWidget()
self.rightWidget = RightWidget()
self.pTalk = PTalkGui("test")
mainLayout = QtGui.QHBoxLayout(self.centerWidget) #水平布局
mainLayout.addWidget(self.leftWidget,1) #注意这里添加的GroupBox
mainLayout.addWidget(self.rightWidget,2) #stretch表示伸展系数
class LeftWidget(QtGui.QGroupBox):
def __init__(self, parent = None):
super(LeftWidget, self).__init__()
self.setTitle("Start client:")
self.setStyleSheet("background-color: rgb(200, 200, 255);") #改变程序的界面颜色
personLabel = QtGui.QLabel("Users:")
##此处为最核心部分,需要好好研究 ??
self.listWidget = QtGui.QListWidget()
item = QtGui.QListWidgetItem(self.listWidget)
self.listWidget.clear()
serverLabel = QtGui.QLabel("Server:")
self.serverEdit = QtGui.QLineEdit("localhost") #定义服务端
portLabel = QtGui.QLabel("Port:") #portLabel.setStyleSheet("""border-color: rgb(0, 85, 255); color: rgb(255, 85, 0);""")
self.portEdit = QtGui.QLineEdit("8765") #定义端口
self.connectButton = QtGui.QPushButton("&Connect")
nameLabel = QtGui.QLabel("Name:")
self.nameEdit = QtGui.QLineEdit(os.getenv("USERNAME")) #获取计算机名称
self.statusLabel = QtGui.QLabel("Status Message:")
self.statusEdit = QtGui.QLineEdit("Set your status")
self.chatButton = QtGui.QPushButton("&Chat")
layout = QtGui.QGridLayout()
layout.addWidget(personLabel,0,0)
layout.addWidget(self.listWidget,0,1) #显示获取的聊天客户
layout.addWidget(serverLabel,1,0)
layout.addWidget(self.serverEdit,1,1)
layout.addWidget(portLabel,2,0)
layout.addWidget(self.portEdit,2,1)
layout.addWidget(self.connectButton,3,0)
layout.addWidget(nameLabel,4,0)
layout.addWidget(self.nameEdit,4,1)
layout.addWidget(self.statusLabel,5,0)
layout.addWidget(self.statusEdit,5,1)
layout.addWidget(self.chatButton,6,0)
layout.setColumnStretch(1, 10)
self.setLayout(layout)
class RightWidget(QtGui.QGroupBox):
def __init__(self, parent = None):
super(RightWidget, self).__init__()
self.setTitle('Chat Room:')
self.messageBrowser = QtGui.QTextBrowser()
messageLabel = QtGui.QLabel("Message:")
self.messageEdit = QtGui.QLineEdit("")
layout = QtGui.QGridLayout()
layout.addWidget(self.messageBrowser)
layout.addWidget(messageLabel)
layout.addWidget(self.messageEdit)
self.setLayout(layout)
class PersonWidget(QtGui.QWidget):
def __init__(self,parent = None):
super(PersonWidget,self).__init__()
layout = QtGui.QHBoxLayout()
self.setLayout(layout)
if __name__ == "__main__":
app = QtGui.QApplication(sys.argv)
cd = ClientGui()
cd.show()
sys.exit(app.exec_())
qt4guiPTalk.py:
import os,sys
from PyQt4 import QtCore, QtGui
reload(sys)
sys.setdefaultencoding('utf-8')
class PTalkGui(QtGui.QMainWindow):
def __init__(self,parent=None):
super(PTalkGui, self).__init__()
self.setGeometry(200, 200, 400, 500) #窗口位置的x和y坐标,窗口的宽度和高度
self.setWindowTitle("聊天".decode('utf-8')) #中文显示 .decode('utf-8')
self.tabWidget = QtGui.QTabWidget()
self.tabWidget.setTabsClosable(True)
#self.tabItemWidget=tabItemWidget(parent) #此处需要注意parent的继承关系
self.setCentralWidget(self.tabWidget)
def closeEvent(self, event):
self.tabWidget.clear()
print "close"
event.accept()
class tabItemWidget(QtGui.QWidget):
def __init__(self,parent = None):
super(tabItemWidget, self).__init__()
self.messageBrowser = QtGui.QTextBrowser(parent)
messageLabel = QtGui.QLabel()
messageLabel.setText("Message:")
self.messageEdit = QtGui.QLineEdit(parent)
self.messageEdit.setTextMargins(0, 0, 4, 20) #QLineEdit.setTextMargins (self, int left, int top, int right, int bottom)
layout = QtGui.QGridLayout()
layout.addWidget(self.messageBrowser)
layout.addWidget(messageLabel)
layout.addWidget(self.messageEdit)
self.setLayout(layout)
if __name__ == "__main__":
app = QtGui.QApplication(sys.argv)
cd = PTalkGui()
cd.show()
sys.exit(app.exec_())
client.py:
# -*- coding: utf-8 -*-
import sys,time
from twisted.internet.protocol import ClientFactory,Protocol
from PyQt4 import QtCore, QtGui
import qt4reactor
from qt4guiClient import *
from qt4guiPTalk import *
app=QtGui.QApplication(['Client'])
GUI = ClientGui()
LwGUI = GUI.leftWidget
RwGUI = GUI.rightWidget
nowtime = time.strftime(' %H:%M:%S ')
talkList = []
PGUI = PTalkGui(LwGUI)
reactor=qt4reactor.install()
MsgRcv = ""
MsgSnd = ""
class Echo(Protocol): #定义协议
def connectionMade(self):
pass
def dataReceived(self,data):
MsgRcv = data.split(">>:")
if MsgRcv[0] =="USEREXISTED":
userName = MsgRcv[1]
content = MsgRcv[2]
RwGUI.messageBrowser.append(userName+content+",请修改用户名称。".decode('utf-8')+"\n") ##改为状态栏显示
LwGUI.nameEdit.setEnabled(True)
LwGUI.statusEdit.setEnabled(True)
LwGUI.chatButton.setEnabled(True)
elif MsgRcv[0] =="USERLIST":
global i
i = 0
print "USERLIST"
LwGUI.listWidget.clear()
usrStatus = data.split(">>>>")
for j in usrStatus:
MsgRcv = j.split(">>:")
strMsg = str(MsgRcv) #列表转为字符串后才能够进行比较
if strMsg != "['']":
userName = MsgRcv[1]
statusMessage = MsgRcv[2]
if userName != LwGUI.nameEdit.text().__str__().__str__(): #用户名不为本用户
item = QtGui.QListWidgetItem(LwGUI.listWidget)
personWidget = PersonWidget()
item.setSizeHint(personWidget.sizeHint())
LwGUI.listWidget.insertItem(i,item) #
LwGUI.listWidget.setItemWidget(item,personWidget)
LwGUI.listWidget.item(i).setText(userName)
i = i+1
elif MsgRcv[0] =="NEWUSER":
print "NEWUSER"
# print MsgRcv
j = LwGUI.listWidget.count()
userName = MsgRcv[1]
statusMessage = MsgRcv[2]
item = QtGui.QListWidgetItem(LwGUI.listWidget)
personWidget = PersonWidget()
item.setSizeHint(personWidget.sizeHint())
LwGUI.listWidget.insertItem(j,item)
LwGUI.listWidget.setItemWidget(item,personWidget)
LwGUI.listWidget.item(j).setText(userName)
elif MsgRcv[0] =="LOGOUT": #外部用户注销
print "LOGOUT"
userName = MsgRcv[1]
print userName
for i in xrange(LwGUI.listWidget.count()):
token = LwGUI.listWidget.item(i).text().__str__().__str__()
print token
if token == userName:
LwGUI.listWidget.takeItem(i)
RwGUI.messageBrowser.append(token + "离开房间".decode('utf-8')+"\n")
break
elif MsgRcv[0] =="COMMONCHAT": #公共信息
userName = MsgRcv[1]
content = MsgRcv[2].decode('utf-8')
if userName != LwGUI.nameEdit.text().__str__().__str__():
RwGUI.messageBrowser.append(userName + nowtime +" >> " + content+"\n")
elif MsgRcv[0] =="NEWPRIVATE":
userName = MsgRcv[1]
recipientName = MsgRcv[2]
if PGUI.tabWidget.count()==0: #如果子窗口之前关闭过
del talkList[:]
if recipientName in talkList:
pass
else:
talkList.append(recipientName)
mytabItemWidget=tabItemWidget(LwGUI)
PGUI.tabWidget.addTab(mytabItemWidget,recipientName)
PGUI.show()
currentIndex = PGUI.tabWidget.indexOf(mytabItemWidget)
QtCore.QObject.connect(mytabItemWidget.messageEdit,QtCore.SIGNAL("returnPressed()"),lambda:sendPMessage(currentIndex))
elif MsgRcv[0] =="PRIVATECHAT":
print "PRIVATECHAT"
print data
userName = MsgRcv[1]
recipientName = MsgRcv[2]
content = MsgRcv[3]
if PGUI.tabWidget.count()==0: #如果子窗口之前关闭过
del talkList[:]
if recipientName not in talkList:
talkList.append(recipientName)
mytabItemWidget=tabItemWidget(LwGUI)
PGUI.tabWidget.addTab(mytabItemWidget,recipientName)
PGUI.show()
currentIndex = PGUI.tabWidget.indexOf(mytabItemWidget)
QtCore.QObject.connect(mytabItemWidget.messageEdit,QtCore.SIGNAL("returnPressed()"),lambda:sendPMessage(currentIndex))
j = 0
for i in talkList:
print i
if PGUI.tabWidget.tabText(j) == recipientName:
print "yes"
PGUI.tabWidget.widget(j).messageBrowser.append(recipientName + nowtime +" >> " + content.decode('utf-8')+"\n")
j=j+1
class EchoClientFactory(ClientFactory):
def startedConnecting(self, connector):
pass
def buildProtocol(self, addr):
RwGUI.messageBrowser.append("Establish connection."+"\n")
LwGUI.connectButton.setEnabled(False)
LwGUI.chatButton.setEnabled(True)
return Echo()
def clientConnectionLost(self, connector, reason):
LwGUI.connectButton.setEnabled(True)
LwGUI.chatButton.setEnabled(False)
def clientConnectionFailed(self, connector, reason):
LwGUI.connectButton.setEnabled(True)
LwGUI.chatButton.setEnabled(False)
def startConnect(): #按下连接按钮
global connection
connection=reactor.connectTCP(LwGUI.serverEdit.text().__str__().__str__(),int(LwGUI.portEdit.text().__str__().__str__()) , EchoClientFactory())
def startChat(): #按下聊天按钮
global connection
userName = LwGUI.nameEdit.text().__str__().__str__()
password = "" ##暂时未添加用户密码
statusMessage = LwGUI.statusEdit.text().__str__().__str__()
if (userName != ""):
if statusMessage == "Set your status":
statusMessage = "Available"
MsgSnd = "LOGIN" + "<<: username statusmessage connection.transport.write lwgui.connectbutton.setenabled lwgui.nameedit.setenabled lwgui.statusedit.setenabled lwgui.chatbutton.setenabled qtcore.qobject.connect else: pass def sendmessage global connection content="RwGUI.messageEdit.text().__str__().__str__()" msgsnd="COMMONCHAT" rwgui.messagebrowser.append nowtime>> " + content.decode('utf-8')+"\n")
RwGUI.messageEdit.clear()
def sendPMessage(item): #发送私有消息
global connection
print "sendPMessage"
userName = LwGUI.nameEdit.text().__str__().__str__()
recipientName=PGUI.tabWidget.tabText(item).__str__().__str__()
content=PGUI.tabWidget.widget(item).messageEdit.text().__str__().__str__()
print content
MsgSnd = "PRIVATECHAT" + "<<: recipientname content print msgsnd connection.transport.write pgui.tabwidget.widget nowtime>> " + content.decode('utf-8')+"\n")
PGUI.tabWidget.widget(item).messageEdit.clear()
def startPTalk(item):
global connection
userName = LwGUI.nameEdit.text().__str__().__str__()
recipientName=item.text().__str__().__str__()
if PGUI.tabWidget.count()==0: #如果子窗口之前关闭过
del talkList[:]
print talkList
if recipientName not in talkList:
talkList.append(recipientName)
mytabItemWidget=tabItemWidget(LwGUI)
PGUI.tabWidget.addTab(mytabItemWidget,recipientName)
PGUI.show()
currentIndex = PGUI.tabWidget.indexOf(mytabItemWidget)
print "currentIndex " + str(currentIndex)
MsgSnd = "NEWPRIVATE" + "<<: recipientname connection.transport.write qtcore.qobject.connect def closeptalk global connection pgui.tabwidget.removetab if in talklist: talklist.remove print talklist closetalk for i gui.show reactor.runreturn will run until ctrl_c is pressed sys.exit>