¿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.
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:
Con esta:
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:
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.