def initUI(self):
        #inicializar los elementos de la vista
        self.entrada = QtGui.QLineEdit(); #input para escribir el mensaje
        self.entrada.setReadOnly(False);

        self.mensajes = QtGui.QTextEdit(); #donde se van a mostrar los mensajes
        self.mensajes.setReadOnly(True);
        
        #se crea el objeto Mensajes que se va a encargar de escuchar y mandar texto
        self.manejadorMensajes = Mensajes(self.ipPropio,self.puertoPropio,self.ipRemoto,self.puertoRemoto,self.nombrePropio,self.mensajes);

        self.buttonEnviar = QtGui.QPushButton('Enviar'); #boton para enviar un texto
        self.buttonEnviar.clicked.connect(self.enviar);
        
        self.buttonLlamar = QtGui.QPushButton('Llamar'); #boton para iniciar una llamada
        self.buttonLlamar.clicked.connect(self.iniciarVideoLlamada);
        
        #se crea el objeto Llamadas, que es va a encargar de escuchar audio del micrófono, mandarlo al otro equipo, y reproducirlo
        self.manejadorLlamadas = Llamadas(self.nombrePropio,self.nombreRemoto,self.ipPropio,self.puertoPropio,self.ipRemoto,self.puertoRemoto);
        self.manejadorLlamadas.setBotonLlamar(self.buttonLlamar); #se agrega el boton a Llamadas para que cambie su texto al llamar
        
       	grid = QtGui.QGridLayout();

        grid.addWidget(self.mensajes,1,0,1,6);
        grid.addWidget(self.entrada,4,0,1,5);
        
        grid.addWidget(self.buttonEnviar, 4,5);
        grid.addWidget(self.buttonLlamar, 4,6);
        
        self.setLayout(grid);

        self.setGeometry(300, 200, 600, 400)
        self.setWindowTitle('Chat de ' + self.nombrePropio + " a " + self.nombreRemoto)
    def initUI(self):
        # inicializar los elementos de la vista
        self.entrada = QtGui.QLineEdit()
        # input para escribir el mensaje
        self.entrada.setReadOnly(False)

        self.mensajes = QtGui.QTextEdit()
        # donde se van a mostrar los mensajes
        self.mensajes.setReadOnly(True)

        # se crea el objeto Mensajes que se va a encargar de escuchar y mandar texto
        self.manejadorMensajes = Mensajes(
            self.ipPropio, self.puertoPropio, self.ipRemoto, self.puertoRemoto, self.nombre, self.mensajes
        )

        buttonEnviar = QtGui.QPushButton("Enviar")
        # boton para enviar un texto
        buttonEnviar.clicked.connect(self.enviar)

        # se crea el objeto Llamadas, que es va a encargar de escuchar audio del micrófono, mandarlo al otro equipo, y reproducirlo
        self.manejadorLlamadas = Llamadas(self.ipPropio, self.puertoPropio + 1, self.ipRemoto, self.puertoRemoto + 1)

        self.buttonLlamar = QtGui.QPushButton("Llamar")
        # boton para iniciar una llamada
        self.buttonLlamar.clicked.connect(self.manejadorLlamadas.llamar)

        self.manejadorLlamadas.setBotonLlamar(self.buttonLlamar)
        # se agrega el boton a Llamadas para que cambie su texto al llamar

        grid = QtGui.QGridLayout()

        grid.addWidget(self.mensajes, 1, 0, 1, 6)
        grid.addWidget(self.entrada, 4, 0, 1, 5)

        grid.addWidget(buttonEnviar, 4, 5)
        grid.addWidget(self.buttonLlamar, 4, 6)

        self.setLayout(grid)

        self.setGeometry(300, 200, 600, 400)
        self.setWindowTitle("Chat")
        # threads para escuchar mensajes de texto y llamadas
        try:
            self.threadMensajes = threading.Thread(target=self.manejadorMensajes.escuchar)
            self.threadEsperaLlamada = threading.Thread(target=self.esperarLlamada)
        except Exception as e:
            print "Error al crear threads", traceback.format_exc()
class chatUserUI(QtGui.QWidget):
                
    #de aquí se toman los datos de la vista anterior
    def __init__(self,nombreA,nombreB,ipA, ipB, puertoA, puertoB):
        super(chatUserUI, self).__init__()
        
        self.nombrePropio=nombreA;
        self.nombreRemoto=nombreB;
        self.ipPropio = ipA;
        self.ipRemoto = ipB;
        self.puertoPropio = int(puertoA);
        self.puertoRemoto = int(puertoB);
        self.initUI();

    def initUI(self):
        #inicializar los elementos de la vista
        self.entrada = QtGui.QLineEdit(); #input para escribir el mensaje
        self.entrada.setReadOnly(False);

        self.mensajes = QtGui.QTextEdit(); #donde se van a mostrar los mensajes
        self.mensajes.setReadOnly(True);
        
        #se crea el objeto Mensajes que se va a encargar de escuchar y mandar texto
        self.manejadorMensajes = Mensajes(self.ipPropio,self.puertoPropio,self.ipRemoto,self.puertoRemoto,self.nombrePropio,self.mensajes);

        self.buttonEnviar = QtGui.QPushButton('Enviar'); #boton para enviar un texto
        self.buttonEnviar.clicked.connect(self.enviar);
        
        self.buttonLlamar = QtGui.QPushButton('Llamar'); #boton para iniciar una llamada
        self.buttonLlamar.clicked.connect(self.iniciarVideoLlamada);
        
        #se crea el objeto Llamadas, que es va a encargar de escuchar audio del micrófono, mandarlo al otro equipo, y reproducirlo
        self.manejadorLlamadas = Llamadas(self.nombrePropio,self.nombreRemoto,self.ipPropio,self.puertoPropio,self.ipRemoto,self.puertoRemoto);
        self.manejadorLlamadas.setBotonLlamar(self.buttonLlamar); #se agrega el boton a Llamadas para que cambie su texto al llamar
        
       	grid = QtGui.QGridLayout();

        grid.addWidget(self.mensajes,1,0,1,6);
        grid.addWidget(self.entrada,4,0,1,5);
        
        grid.addWidget(self.buttonEnviar, 4,5);
        grid.addWidget(self.buttonLlamar, 4,6);
        
        self.setLayout(grid);

        self.setGeometry(300, 200, 600, 400)
        self.setWindowTitle('Chat de ' + self.nombrePropio + " a " + self.nombreRemoto)
    
    """
        Función para agregar un mensaje al historial de mensajes
        
        @param str nombre Quién escribió el mensaje
        @param str mensaje
    """
    def agregarMensaje(self,nombre,mensaje):
        self.mensajes.append(nombre + ":" + mensaje);
        
    #funcion para concatenar el mensaje que se envía a la vista y llamar a manejadorMensajes para que mande el mensaje
    def enviar(self):
        mensaje=str(self.entrada.text())
        self.entrada.setText(""); #borro el campo
    	self.mensajes.append(self.nombrePropio + ":" + mensaje); #agrego el mensaje al cuadro
        self.manejadorMensajes.enviar(mensaje) #mando el mensaje

    #función que llama a manejadorLlamadas para abrir un método que escuche un servidor
    def esperarLlamada(self):
        self.manejadorLlamadas.esperarLlamada();
    
    #función para iniciar intercambiando audio y vídeo
    def iniciarVideoLlamada(self):
        self.manejadorLlamadas.llamar();
        
    #de esta manera le digo a la interfaz del cliente que cerré la conversación con este usuario
    def closeEvent(self,event):
        self.emit(QtCore.SIGNAL("cerrarChat(QString)"),self.nombreRemoto);
        event.accept();
class chatUserUI(QtGui.QWidget):

    # de aquí se toman los datos de la vista anterior
    def __init__(self, nombre, ipA, ipB, puertoA, puertoB):
        super(chatUserUI, self).__init__()
        self.nombre = nombre
        self.ipPropio = ipA
        self.ipRemoto = ipB
        self.puertoPropio = int(puertoA)
        self.puertoRemoto = int(puertoB)
        self.initUI()

    def initUI(self):
        # inicializar los elementos de la vista
        self.entrada = QtGui.QLineEdit()
        # input para escribir el mensaje
        self.entrada.setReadOnly(False)

        self.mensajes = QtGui.QTextEdit()
        # donde se van a mostrar los mensajes
        self.mensajes.setReadOnly(True)

        # se crea el objeto Mensajes que se va a encargar de escuchar y mandar texto
        self.manejadorMensajes = Mensajes(
            self.ipPropio, self.puertoPropio, self.ipRemoto, self.puertoRemoto, self.nombre, self.mensajes
        )

        buttonEnviar = QtGui.QPushButton("Enviar")
        # boton para enviar un texto
        buttonEnviar.clicked.connect(self.enviar)

        # se crea el objeto Llamadas, que es va a encargar de escuchar audio del micrófono, mandarlo al otro equipo, y reproducirlo
        self.manejadorLlamadas = Llamadas(self.ipPropio, self.puertoPropio + 1, self.ipRemoto, self.puertoRemoto + 1)

        self.buttonLlamar = QtGui.QPushButton("Llamar")
        # boton para iniciar una llamada
        self.buttonLlamar.clicked.connect(self.manejadorLlamadas.llamar)

        self.manejadorLlamadas.setBotonLlamar(self.buttonLlamar)
        # se agrega el boton a Llamadas para que cambie su texto al llamar

        grid = QtGui.QGridLayout()

        grid.addWidget(self.mensajes, 1, 0, 1, 6)
        grid.addWidget(self.entrada, 4, 0, 1, 5)

        grid.addWidget(buttonEnviar, 4, 5)
        grid.addWidget(self.buttonLlamar, 4, 6)

        self.setLayout(grid)

        self.setGeometry(300, 200, 600, 400)
        self.setWindowTitle("Chat")
        # threads para escuchar mensajes de texto y llamadas
        try:
            self.threadMensajes = threading.Thread(target=self.manejadorMensajes.escuchar)
            self.threadEsperaLlamada = threading.Thread(target=self.esperarLlamada)
        except Exception as e:
            print "Error al crear threads", traceback.format_exc()

    # funcion para concatenar el mensaje que se envía a la vista y llamar a manejadorMensajes para que mande el mensaje
    def enviar(self):
        mensaje = str(self.entrada.text())
        self.entrada.setText("")
        # borro el campo
        self.mensajes.append(self.nombre + ":" + mensaje)
        # agrego el mensaje al cuadro
        self.manejadorMensajes.enviar(mensaje)  # mando el mensaje

    # función que llama a manejadorLlamadas para abrir un método que escuche un servidor
    def esperarLlamada(self):
        self.manejadorLlamadas.esperarLlamada()

    # funcion que inicia los hilos del chat
    def chatini(self):
        try:
            self.threadMensajes.start()
            self.threadEsperaLlamada.start()
        except Exception as e:
            print "Error al inicializar los threads", traceback.format_exc()
class chatUserUI(QtGui.QWidget):
                
    #de aquí se toman los datos de la vista anterior
    def __init__(self,nombre,ipA, ipB, puertoA, puertoB):
        super(chatUserUI, self).__init__()
        self.nombre=nombre
        self.ipPropio = ipA
        self.ipRemoto = ipB
        self.puertoPropio = int(puertoA)
        self.puertoRemoto = int(puertoB)
        self.initUI()

    def initUI(self):
        #inicializar los elementos de la vista
        self.entrada = QtGui.QLineEdit(); #input para escribir el mensaje
        self.entrada.setReadOnly(False);

        self.mensajes = QtGui.QTextEdit(); #donde se van a mostrar los mensajes
        self.mensajes.setReadOnly(True);
        
        #se crea el objeto Mensajes que se va a encargar de escuchar y mandar texto
        self.manejadorMensajes = Mensajes(self.ipPropio,self.puertoPropio,self.ipRemoto,self.puertoRemoto,self.nombre,self.mensajes);

        buttonEnviar = QtGui.QPushButton('Enviar'); #boton para enviar un texto
        buttonEnviar.clicked.connect(self.enviar);
        
        self.buttonLlamar = QtGui.QPushButton('Llamar'); #boton para iniciar una llamada
        self.buttonLlamar.clicked.connect(self.iniciarVideoLlamada);
        
        #se crea el objeto Llamadas, que es va a encargar de escuchar audio del micrófono, mandarlo al otro equipo, y reproducirlo
        self.manejadorLlamadas = Llamadas(self.ipPropio,self.puertoPropio,self.ipRemoto,self.puertoRemoto);
        self.manejadorLlamadas.setBotonLlamar(self.buttonLlamar); #se agrega el boton a Llamadas para que cambie su texto al llamar
        
        self.manejadorVideos = Video("VideoLlamada",self.ipPropio,self.puertoPropio,self.ipRemoto,self.puertoRemoto);
        
       	grid = QtGui.QGridLayout();

        grid.addWidget(self.mensajes,1,0,1,6);
        grid.addWidget(self.entrada,4,0,1,5);
        
        grid.addWidget(buttonEnviar, 4,5);
        grid.addWidget(self.buttonLlamar, 4,6);
        
        self.setLayout(grid);

        self.setGeometry(300, 200, 600, 400)
        self.setWindowTitle('Chat')
        
    #funcion para concatenar el mensaje que se envía a la vista y llamar a manejadorMensajes para que mande el mensaje
    def enviar(self):
        mensaje=str(self.entrada.text())
        self.entrada.setText(""); #borro el campo
    	self.mensajes.append(self.nombre + ":" + mensaje); #agrego el mensaje al cuadro
        self.manejadorMensajes.enviar(mensaje) #mando el mensaje

    #función que llama a manejadorLlamadas para abrir un método que escuche un servidor
    def esperarLlamada(self):
        self.manejadorLlamadas.esperarLlamada();
    
    #función para iniciar intercambiando audio y vídeo
    def iniciarVideoLlamada(self):
        self.manejadorLlamadas.llamar();
        #self.manejadorVideos.iniciarVideoLlamada();
    
    #funcion que incia el servidor xmlrpc del cliente con todos los métodos de mensajes,audio y video
    def iniciarServidor(self):
        server = SimpleXMLRPCServer((str(self.ipPropio), int(self.puertoPropio)),allow_none=True)
        server.register_function(self.manejadorMensajes.recibir, "send") #agrego la función para concatenar mensajes al historial de mensajes
        server.register_function(self.manejadorLlamadas.reproducirLlamada, "reproducirLlamada") #agrego la función para recibir un audio y reproducirlo
        server.register_function(self.manejadorLlamadas.iniciarLlamada,"iniciarLlamada") #agrego la función para iniciar una llamada con este servidor
        server.register_function(self.manejadorVideos.sendFrames, 'sendFrames');
        server.register_function(self.manejadorVideos.startPlayFrames, 'startPlayFrames');
        server.serve_forever();
    
    #funcion que inicia los hilos del chat        
    def chatini(self):
        try:
            threadServidor = threading.Thread(target=self.iniciarServidor);
            threadServidor.start();
        except Exception as e:
            print "Error al inicializar los threads", traceback.format_exc()