使用PyQt4和twisted写的局域网聊天室(4)

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 + "<<:" +password + "<<:" + statusMessage
        connection.transport.write(MsgSnd)
        LwGUI.connectButton.setEnabled(False)
        LwGUI.nameEdit.setEnabled(False)
        LwGUI.statusEdit.setEnabled(False)
        LwGUI.chatButton.setEnabled(False)
        QtCore.QObject.connect(RwGUI.messageEdit,QtCore.SIGNAL("returnPressed()"),sendMessage) #发送公共消息
    else:                                                                                      ##状态栏显示需要添加用户名
        pass

def sendMessage():                               #发送公共消息
    global connection
    userName = LwGUI.nameEdit.text().__str__().__str__()
    content = RwGUI.messageEdit.text().__str__().__str__()
    MsgSnd = "COMMONCHAT" + "<<:" + userName + "<<:" + content
    connection.transport.write(MsgSnd)
    RwGUI.messageBrowser.append(userName + 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" + "<<:" +userName + "<<:" + recipientName + "<<:" + content
    print MsgSnd
    connection.transport.write(MsgSnd)
    PGUI.tabWidget.widget(item).messageBrowser.append(userName + 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" + "<<:"+userName + "<<:" + recipientName
        connection.transport.write(MsgSnd)   

        QtCore.QObject.connect(mytabItemWidget.messageEdit,QtCore.SIGNAL("returnPressed()"),lambda:sendPMessage(currentIndex))
    
def closePTalk(item):
    global connection
    recipientName = PGUI.tabWidget.tabText(item) 
    
    PGUI.tabWidget.removeTab(item)  
    
    if recipientName in talkList:                                 ##是否告知对方私有会话已关闭?需要告知
        talkList.remove(recipientName) 
        print talkList

def closeTalk():
    print "closeTalk"
    global connection
    for i in talkList:
        PGUI.tabWidget.removeTab(i)
        talkList.remove(i)        
    
QtCore.QObject.connect(LwGUI.connectButton,QtCore.SIGNAL("clicked()"),startConnect) #按下连接按钮
QtCore.QObject.connect(LwGUI.chatButton,QtCore.SIGNAL("clicked()"),startChat)       # 按下聊天按钮
QtCore.QObject.connect(LwGUI.listWidget,QtCore.SIGNAL("itemDoubleClicked(QListWidgetItem*)"),startPTalk)
QtCore.QObject.connect(PGUI.tabWidget,QtCore.SIGNAL("tabCloseRequested(int)"),closePTalk)                                                                           

GUI.show()
reactor.runReturn()                            #reactor will run until Ctrl_C is pressed
sys.exit(app.exec_())
posted @ 2014-11-02 10:40  WeiJY  阅读(447)  评论(0编辑  收藏  举报