Fase 4: Extender la Aplicación con una Interfaz Gráfica para el Cliente usando Tkinter
Objetivo
Desarrollar una interfaz gráfica para el cliente del chat usando la biblioteca Tkinter. La interfaz permitirá una experiencia más amigable para enviar y recibir mensajes en tiempo real.
Conceptos Clave
- Interfaz Gráfica (GUI): Uso de Tkinter para construir interfaces gráficas básicas en Python.
- Interactividad**: Implementar botones, entradas de texto y listas para mostrar mensajes.
- Hilos en la GUI: Asegurar que la aplicación gráfica sea responsiva mientras maneja múltiples tareas como enviar y recibir mensajes.
Instrucciones
1. Crear la estructura inicial para la GUI
Edita el archivo src/client.py para añadir funcionalidades gráficas. Comienza reemplazando la clase ChatClient por una versión ampliada con Tkinter:
"""
Módulo: client.py
Descripción: Cliente de chat con interfaz gráfica (Tkinter).
"""
import socket
import tkinter as tk
import threading
class ChatClientGUI:
def __init__(self, host, port):
"""
Inicializa el cliente con la dirección y puerto del servidor, y configura la GUI.
:param host: Dirección IP del servidor.
:param port: Puerto del servidor.
"""
self.host = host
self.port = port
self.client_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
self.nickname = ""
self.running = True
self.chat_window = None
self.message_box = None
self.entry_box = None
def connect_to_server(self):
"""
Conecta el cliente al servidor y envía el nickname.
"""
try:
self.client_socket.connect((self.host, self.port))
print("Conectado al servidor")
except Exception as e:
print(f"No se pudo conectar al servidor: {e}")
def send_message(self, message):
"""
Envía un mensaje al servidor.
:param message: Mensaje a enviar.
"""
try:
self.client_socket.sendall(message.encode("utf-8"))
except Exception as e:
print(f"Error al enviar mensaje: {e}")
def receive_messages(self):
"""
Recibe mensajes del servidor y los muestra en la GUI.
"""
while self.running:
try:
= self.client_socket.recv(1024).decode("utf-8")
message if message:
self.chat_window.after(0, self.display_message, message)
else:
break
except Exception as e:
print(f"Error al recibir mensaje: {e}")
break
def display_message(self, message):
"""
Muestra un mensaje en la ventana de chat.
:param message: Mensaje recibido.
"""
self.message_box.insert(tk.END, message)
self.message_box.yview(tk.END)
def setup_gui(self):
"""
Configura la ventana principal de la interfaz gráfica.
"""
self.window = tk.Tk()
self.window.title("Chat Cliente")
# Ventana de ingreso de nickname
self.nickname_window = tk.Frame(self.window)
self.nickname_window.pack(padx=10, pady=10)
self.nickname_label = tk.Label(self.nickname_window, text="Nick:")
self.nickname_label.pack(padx=10, pady=10)
self.nickname_entry = tk.Entry(self.nickname_window)
self.nickname_entry.pack(padx=10, pady=10)
self.nickname_button = tk.Button(
self.nickname_window, text="OK", command=self.set_nickname
)self.nickname_button.pack(padx=10, pady=10)
self.window.mainloop()
def set_nickname(self):
"""
Configura el nickname del usuario y prepara la ventana de chat.
"""
self.nickname = self.nickname_entry.get()
if self.nickname:
self.client_socket.sendall(self.nickname.encode("utf-8"))
self.nickname_window.pack_forget() # Oculta la ventana de nickname
self.create_chat_window() # Muestra la ventana de chat
def create_chat_window(self):
"""
Crea la ventana de chat principal con opciones para enviar y recibir mensajes.
"""
self.chat_window = tk.Frame(self.window)
self.chat_window.pack(padx=10, pady=10)
self.message_box = tk.Listbox(self.chat_window, height=15, width=50)
self.message_box.pack(padx=10, pady=10)
self.entry_box = tk.Entry(self.chat_window, width=40)
self.entry_box.pack(padx=10, pady=10)
self.send_button = tk.Button(
self.chat_window, text="Enviar", command=self.on_send_message
)self.send_button.pack(padx=10, pady=10)
# Hilo para recibir mensajes
=self.receive_messages, daemon=True).start()
threading.Thread(target
def on_send_message(self):
"""
Envía un mensaje al servidor y lo muestra en el cliente.
"""
= self.entry_box.get()
message if message:
self.send_message(message)
self.display_message(f"{self.nickname}: {message}")
self.entry_box.delete(0, tk.END)
if __name__ == "__main__":
= "127.0.0.1"
SERVER_HOST = 12345
SERVER_PORT = ChatClientGUI(SERVER_HOST, SERVER_PORT)
client
client.connect_to_server() client.setup_gui()
2. Probar la interfaz gráfica
Asegúrate de que el servidor está ejecutándose:
python src/server.py
Inicia el cliente con la nueva interfaz gráfica:
python src/client.py
Conecta múltiples clientes y verifica que puedan enviar y recibir mensajes. Asegúrate de que la interfaz es funcional.
3. Versionar los cambios
Agrega y confirma los archivos modificados:
git add .
git commit -m "Fase 4: Implementación de la interfaz gráfica del cliente con Tkinter"
Sube los cambios al repositorio remoto:
git push origin main
Pruebas
- Verifica que el cliente gráfico se conecta correctamente al servidor.
- Confirma que los mensajes enviados y recibidos se muestran correctamente en la interfaz.
- Realiza pruebas con múltiples clientes para asegurar la funcionalidad del sistema completo.
Conclusiones
En esta fase, se extendió el cliente del chat incorporando una interfaz gráfica interactiva. Esto proporciona una experiencia de usuario más amigable y permite manejar tareas de comunicación en segundo plano sin afectar la responsividad de la interfaz.