【PyQt4 实例20】基于TCP网络的聊天室程序

  本代码支持中文输入,这一点居然耗费了我一周的时间,坑爹啊

tcpServer:

# -*- coding: utf-8 -*-
from PyQt4.QtGui import *
from PyQt4.QtCore import *
import sys
from PyQt4.QtNetwork import *

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.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("TCP Server")
        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("Create"))
        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))
    

                


        
        
app=QApplication(sys.argv)
dialog=TcpServer()
dialog.show()
app.exec_()
tcpCilent:

# -*- coding: utf-8 -*-

from PyQt4.QtGui import *
from PyQt4.QtCore import *
import sys
from PyQt4.QtNetwork import *

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())
        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.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())
        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))
        


app=QApplication(sys.argv)
dialog=TcpClient()
dialog.show()
app.exec_()


你可能感兴趣的:(python)