es.davy.ai

Preguntas y respuestas de programación confiables

¿Tienes una pregunta?

Si tienes alguna pregunta, puedes hacerla a continuación o ingresar lo que estás buscando.

¿Cómo puedo ejecutar al mismo tiempo una interfaz gráfica de usuario (GUI) de Python GTK y un chat?

¿Alguien puede ayudarme con Python GTK + sockets? Estoy intentando hacer un chat, así que estoy ejecutando esto para recibir mensajes de otros usuarios:

def socket_recv(socket, buffer):
    while True:
        try:
            message = socket.recv(1024).decode()
            end_iter = buffer.get_end_iter()
            buffer.insert(end_iter, message + "\n")
            while Gtk.events_pending():
                Gtk.main_iteration()
        except:
            print("Has sido desconectado del servidor")
            socket.close()
            break

En mi función principal, estoy intentando ejecutar este evento:

def onConnect(self, widget):
        self.nickname = self.nickname_entry.get_text().strip()
        self.address = self.address_entry.get_text().strip()

        if self.nickname == "" or self.address == "": 
            self.error_message.show()
            return

        HOST, PORT = self.address.split(':')
        PORT = int(PORT)
        self.sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
        self.sock.connect((HOST, PORT))

        self.sock.send(str.encode(self.nickname))

        self.builder.add_from_file("interface.glade")  
        self.builder.connect_signals(self)

        self.chat_text.set_editable(False)
        self.chat_text.set_wrap_mode(3)
        self.chat_buffer = self.chat_text.get_buffer()
        self.chat_buffer.set_text("Inicio del chat\n")
        self.end_iter = self.chat_buffer.get_end_iter()

        self.chatWindow.show()

        while Gtk.events_pending():
            Gtk.main_iteration()

        thread = threading.Thread(target=socket_recv(self.sock, self.chat_buffer))
        thread.start()

Obtengo la dirección y el apodo del usuario en la ventana inicial de la interfaz gráfica y luego intento conectarme al servidor después de que hacen clic en el botón “Conectar”, luego aparece la ventana de chat. Aunque puedo conectarme al servidor, cuando intento ejecutar mi GUI de chat con socket_recv, la GUI se vuelve completamente disfuncional (los botones no se pueden presionar, etc.) y tengo que forzar la salida para cerrar la aplicación.

Soy bastante nuevo en Python, GTK y enhebrado, y agradecería cualquier ayuda.

Tags:  , , , ,

Answer

  1. Avatar for davy.ai

    Parece que estás ejecutando tu función “socket_recv” en el hilo principal, lo cual está causando que tu interfaz gráfica (GUI) se bloquee. Para solucionar esto, puedes utilizar el módulo “threading” para ejecutar tu función “socket_recv” en un hilo separado. Ya has iniciado un hilo en tu código, pero necesitas pasar la función en sí misma como objetivo (target), no el resultado de llamar a la función.

    Reemplaza esta línea:

    thread = threading.Thread(target=socket_recv(self.sock, self.chat_buffer))
    

    Con esta:

    thread = threading.Thread(target=socket_recv, args=(self.sock, self.chat_buffer))
    

    Esto pasará la función y sus argumentos al nuevo hilo, el cual se ejecutará de forma independiente al hilo principal y permitirá que tu GUI se mantenga receptiva.

    Además, es una buena práctica utilizar un método que sea seguro para hilos (thread-safe) para actualizar tu GUI desde la función “socket_recv”. En lugar de insertar directamente el mensaje en el buffer, utiliza la función “GLib.idle_add” para encolar (queue) la actualización que se realizará por el hilo principal cuando esté listo. Aquí tienes un ejemplo:

    from gi.repository import GLib
    
    def socket_recv(socket, buffer):
        while True:
            try:
                message = socket.recv(1024).decode()
                GLib.idle_add(buffer.insert, buffer.get_end_iter(), message + "\n")
            except:
                print("Te has desconectado del servidor")
                socket.close()
                break
    

    Esto garantizará que las actualizaciones de GUI se manejen de forma segura en el hilo principal.

    ¡Espero que esto sea de ayuda! Avísame si tienes alguna otra pregunta.

Comments are closed.