Programación GUI en Python con Tkinter
Programación GUI en Python con Tkinter
PROGRAMACIÓN EN PYTHON
Course Code: CS721PE
C. RAJEEV
Prof. Asistente
CSE,
MRECW.
UNIDAD-4
UNIDAD - IV
Programación GUI: Introducción, Tkinter y programación en Python
Breve recorrido por otras GUIs, módulos relacionados y otras GUIs.
(HTTP) Servidores
Programación de GUI:
Introducción:
¿Qué es una interfaz gráfica de usuario (GUI)?
La Interfaz Gráfica de Usuario (GUI) no es más que una aplicación de escritorio que te ayuda a
interactuar con las computadoras. Se utilizan para realizar diferentes tareas en los escritorios, laptops
y otros dispositivos electrónicos.
GUIapps likeText-Editorsare used to create, read, update and delete different types of
archivos.
Las aplicaciones GUI como Sudoku, Ajedrez y Solitario son juegos que puedes jugar.
Las aplicaciones GUI como Google Chrome, Firefox y Microsoft Edge se utilizan para navegar a través de
elInternet.
Bibliotecas de Python para crear interfaces gráficas de usuario:
Python ofrece varias opciones/bibliotecas diferentes para escribir programas basados en GUI.
Estos se enumeran a continuación:
Python.
2. JPython: Es la plataforma de Python para Java que proporciona scripts de Python de manera fluida.
wxPython: Es un kit de herramientas GUI de código abierto y multiplataforma escrito en C++. Es uno de los
Hay muchas otras interfaces (Kivy, Python QT) disponibles para GUI. Entre todas
estos, Tkinter es preferido por muchos aprendices y desarrolladores simplemente por lo sencillo
y fácil es.
¿Qué son Tcl, Tk y Tkinter?
Tkinter es la biblioteca GUI predeterminada de Python. Se basa en el kit de herramientas Tk, originalmente
tkinter es un módulo de Python integrado que se utiliza para crear aplicaciones GUI simples. Es el más
>>>import Tkinter
siguientes pasos −
1. importando tkinter
Es igual que importar cualquier otro módulo en el código de Python. Tenga en cuenta que el nombre del
Un bucle de eventos básicamente le dice al código que siga mostrando la ventana hasta que nosotros
window = [Link]()
3.(opcional) Cambia el nombre del título de la ventana como desees con el
[Link](titulo_de_la_ventana).
4. La etiqueta se utiliza para insertar algunos objetos en la ventana. Aquí, estamos añadiendo una etiqueta con
algún texto.
El atributo pack() del widget se utiliza para mostrar el widget en un tamaño que requiere.
5. Finalmente, el método mainloop() para mostrar la ventana hasta que la cierras manualmente.
Widgets de Tk:
Los widgets son algo así como elementos en el HTML. Encontrarás diferentes tipos de widgets para
Estas opciones se pueden usar como pares clave-valor separados por comas.
Estas opciones se pueden usar como pares clave-valor separados por comas.
importar tkinter
top = [Link]()
[Link]()
[Link]()
3. Widget de escala:
El widget de escala se utiliza para implementar el control deslizante gráfico en las aplicaciones de Python para que
el usuario puede deslizarse a través del rango de valores mostrados en el control deslizante y seleccionar uno entre
ellos.
Podemos controlar los valores mínimo y máximo junto con la resolución de la escala.
Sintaxis
w = Escala(superior, opciones)
[Link]()
buclePrincipal()
4. Etiqueta:
La etiqueta se utiliza para especificar la caja contenedora donde podemos colocar el texto o las imágenes.
el widget se utiliza para proporcionar el mensaje al usuario sobre otros widgets utilizados en Python
aplicación.
Hay varias opciones que se pueden especificar para configurar el texto o la parte de la
texto mostrado en la etiqueta.
Sintaxis:
w =Etiqueta (master, opciones)
• master es el parámetro utilizado para representar la ventana principal.
• Hay varias opciones que se utilizan para cambiar el formato del widget.
bg: establecer el color de fondo normal.
bgto establece el color de fondo normal.
comando: llamar a una función.
fuente: para establecer la fuente en la etiqueta del botón.
imagen: para establecer la imagen en el botón.
ancho: para establecer el ancho del botón.
height” to set the height of the button.
Ex:
de tkinter importar *
raíz = Tk()
var = StringVar()
label =Label( root, textvariable=var, relief=RAISED )
¡Hola!? ¿Cómo estás?
[Link]()
[Link]()
alivio
Especifica la apariencia de un
borde decorativo alrededor de la etiqueta.
El valor predeterminado es PLANO.
5. Botón de verificación:
Este widget se utiliza para mostrar una cantidad de opciones a un usuario como botones de alternancia.
el usuario puede entonces seleccionar una o más opciones haciendo clic en el botón correspondiente a cada una
de tkinter import *
importar messagebox
importar tkinter
top = [Link]()
CheckVar1 = IntVar()
CheckVar2 = IntVar()
C1 = Checkbutton(top, text = "Música", variable = CheckVar1, onvalue = 1, offvalue
= 0, altura=5, ancho=20)
C2 = Checkbutton(top, text = "Video", variable = CheckVar2, onvalue = 1, offvalue =
0, altura=5, ancho=20)
[Link]() [Link]() [Link]()
6. Entrada
El widget Entry se utiliza para proporcionar un cuadro de texto de una sola línea al usuario para aceptar un
Widget de Entrada
de tkinter import *
top = Tk()
L1 =Label(top, text="User Name")
[Link]( lado =IZQUIERDA)
E1 = Entrada(principal, bd=5)
[Link](side=RIGHT)
[Link]()
7. Marco:
Se utiliza para organizar el grupo de widgets. Actúa como un contenedor.
que se pueden usar para mantener los otros widgets. Las áreas rectangulares
8. Lista desplegable:
El widget Listbox se utiliza para mostrar una lista de elementos de los cuales un
9. Menu:
El objetivo de este widget es permitirnos crear todo tipo de menús
que puede ser utilizado por nuestras aplicaciones. La funcionalidad central proporciona
de tkinter importar *
importar messagebox
importar tkinter
top = Tk()
Lb1 =Caja de lista(superior)
[Link](1, "Python")
[Link](2, "Perl")
[Link](3, "C")
[Link](4, "PHP")
[Link](5, "JSP")
[Link](6, "Ruby")
[Link]()
[Link]()
Menú
de tkinter importar *
importar messagebox
importar tkinter
top = Tk()
mb=Menubuton( top, text="Archivo", relief=RAISED )
[Link]()
[Link] = Menu( mb, tearoff = 0 )
mb["menu"] = [Link]
Var1 = IntVar()
Var2 = IntVar()
[Link].add_checkbuton( label="Nuevo", variable=Var1 )
[Link].add_checkbuton ( etiqueta="abrir", variable=Var2 )
[Link].add_checkbuton ( label="Guardar", variable=Var2 )
[Link].add_checkbuton ( etiqueta="Guardar como", variable=Var2 )
[Link].add_checkbuton ( label="Cerrar", variable=Var2 )
[Link].add_checkbuton ( label="Salir", variable=Var2 )
[Link]()
[Link]()
10. Botón de menú
Se puede definir como el menú desplegable que se muestra al usuario
todo el tiempo. Se utiliza para ofrecer al usuario una opción para seleccionar el
11. Message:
Se utiliza para mostrar el mensaje al usuario sobre el comportamiento
de la aplicación de python.
Muestra los mensajes de texto al usuario que no se pueden editar.
El texto del mensaje contiene más de una línea. Sin embargo, la
el mensaje solo puede mostrarse en una sola fuente.
12. Cuadro de Mensaje:
de tkinter import *
root = Tk()
var = StringVar()
[Link]()
[Link]()
Widget de cuadro de mensaje
de tkinter import *
desde tkinter import messagebox
top = Tk()
[Link]("100x100")
def helloCallBack():
msg = [Link]( “Say Hello", "Hello World")
B = Botón(top, texto = "Decir Hola", comando = helloCallBack)
[Link](x = 100, y = 100)
[Link]()
13. Botón de opción:
Conjunto de botones de los cuales solo uno puede ser 'presionado' (similar a
14. Scrollbar:
El widget de la barra de desplazamiento se utiliza para desplazar hacia abajo el contenido del
[Link]
Se utiliza para mostrar los datos de texto en la aplicación de Python.
defsel():
selection = "You selected the option " + str([Link]())
[Link](text = selección)
raíz = Tk()
var = IntVar()
R1 = Radiobutton(root, text="C", variable=var, value=1,
comando=sel)
[Link]( ancla = O )
label = Label(root)
[Link]()
[Link]()
Ex: scroll bar:
de tkinter import *
raíz = Tk()
scrollbar = Scrollbar(root)
forline en rango(50):
bucle principal()
Ejemplo: texto
de tkinter importar *
def onclick():
pasar
root = Tk()
Texto(root)
[Link](INSERT, "Hola.....")
[Link](FIN, "Adiós Adiós.....")
[Link]()
text.tag_add("aquí", "1.0", "1.4")
text.tag_add("inicio", "1.8", "1.13")
text.tag_config("aquí", background="amarillo", foreground="azul")
text.tag_config("start", fondo="negro", primer_plano="verde")
[Link]()
17. spinbox:
El widget Spinbox es una variante del widget de entrada estándar de Tkinter, que puede ser
se utiliza para seleccionar de un número fijo de valores.
Ejemplo:
de tkinter import *
master = Tk()
w = Spinbox(maestro, de=0, a=10)
[Link]()
bucle principal()
Breve recorrido por otras interfaces gráficas de usuario
Pmwis es solo una extensión de Tkinter, es la más fácil de instalar (simplemente extrae en
los paquetes de tu sitio).
Es un conjunto de herramientas para construir widgets compuestos de alto nivel en Python usando
el paquete tkinter.
wxPython es de código abierto, lo que significa que es gratis para que cualquiera lo use y el código fuente
el código está disponible para que cualquier persona lo revise y lo modifique. Y cualquiera puede contribuir con correcciones o
mejoras al proyecto.
wxPython es un kit de herramientas multiplataforma. Esto significa que el mismo programa se ejecutará en
En la mayoría de los casos, se utilizan los widgets nativos en cada plataforma para proporcionar un 100% nativo.
GTK son herramientas de desarrollo y kits de herramientas de interfaz de usuario de código abierto y multiplataforma.
marcos
Son marcos populares en uso para Linux porque son de código abierto y brindan
desarrolladores un conjunto de herramientas poderoso para diseñar Interfaces Gráficas de Usuario.
PyGTK es un conjunto de envolturas de Python para la biblioteca de interfaz gráfica de usuario GTK+.
GTK es solo un conjunto de herramientas de widgets para las aplicaciones GNOME (colección de aproximadamente 30)
La navegación web cae bajo la misma arquitectura cliente/servidor que hemos visto.
repetidamente.
Esta vez, los clientes web son navegadores, aplicaciones que permiten a los usuarios encontrar documentos en
Del otro lado están los servidores web, procesos que se ejecutan en el host de un proveedor de información.
computadoras. Estos servidores esperan a los clientes y sus solicitudes de documentos, las procesan y
una aplicación que hace una solicitud de datos a un servidor web se considera un "cliente." Es
es posible crear otros clientes que recuperen documentos o datos de Internet.
Una razón importante para hacer esto es que un navegador ofrece solo una capacidad limitada, es decir, que
por otro lado, un programa cliente tiene la capacidad de hacer más; no solo puede
descargar datos, pero también puede almacenarlos, manipularlos o quizás incluso transmitirlos a
Aplicaciones que utilizan el módulo urllib para descargar o acceder a información en la web
Direcciones). Tales direcciones se utilizan para localizar un documento en la web o para llamar a un CGI
Las URL son parte de un conjunto más amplio de identificadores conocidos como URIs (Identificadores de Recursos Uniformes)
Identificadores).
Una URL es simplemente un URI que utiliza un protocolo o esquema existente (es decir, http, ftp, etc.) como
parte de su dirección.
Al igual que las direcciones callejeras, las direcciones web tienen cierta estructura. Una dirección callejera americana
generalmente es de la forma "número designación de la calle," es decir, 123 Calle Principal. Se diferencia de
prot_sch://net_loc/path;params?query#frag
Una vez más, net_loc puede desglosarse en varios componentes más, algunos requeridos, otros
opcional. La cadena net_loc se ve así:
usuario:contraseña@host:puerto
De los cuatro, el nombre del host es el más importante para ejecutar un servidor web.
El número de puerto es necesario solo si el servidor web está ejecutándose en un número de puerto diferente
Los nombres de usuario y las contraseñas se utilizan solo al hacer conexiones FTP.
Para tratar con URL en funcionalidades y capacidades completamente diferentes. Python proporciona dos
1. Módulo urlparse:
El módulo urlparse proporciona funcionalidad básica para manipular cadenas de URL.
Estas funciones incluyen-
1. urlparse()
2. urlunparse(), y
3. urljoin()
[Link]():
urlparse() descompone una cadena de URL en algunos de los componentes principales (prot_sch,
frag)
defProtSchindica un protocolo de red predeterminado o un esquema de descarga en caso de que no se especifique uno.
proporcionado [Link].
[Link] es una bandera que indica si se permite o no una parte de fragmento de una URL.
>>> [Link]('[Link]
ruta, params, consulta, frag) urltup, que podría ser la salida de urlparse(), en una sola
Cadena URL y la devuelve.
Sintaxis:
urlunparse(urlparse(urlstr))
Ej:
Urlunparse(urlparse('[Link]
Output:
[Link]
En este caso, los parámetros, la consulta y el fragmento están todos ausentes en la URL original.
urljoin() toma la url base y une su ruta base (net_loc más la ruta completa hasta, pero no
incluyendo, un archivo al final) con newurl.
Por ejemplo:
>>> [Link]('[Link] \
... 'current/lib/[Link]')
'[Link]
Módulo urllib:
urllib es un módulo de Python que se puede utilizar para abrir URLs (Localizadores Uniformes de Recursos).
sintaxis:
urlopen(urlstr, postQueryData=None)
urlopen() abre la URL apuntada por urlstr. Si no se proporciona ningún protocolo o esquema de descarga, o
Para todas las solicitudes HTTP, el tipo de solicitud normal es "GET." En estos casos, la cadena de consulta
por ejemplo, si nuestro objeto de archivo es f, entonces nuestro "manejador" admitiría la lectura esperada
filename es el nombre del archivo local que contiene los datos descargados.
mime_hdrs es el conjunto de encabezados MIME devueltos por el servidor web que responde.
[Link]() y urllib.quote_plus():
Las funciones quote() toman datos de URL y los "codifican" para que sean "aptos" para
inclusión como parte de una cadena de URL.
Sintaxis:
citar(urldata, seguro='/')
Los caracteres que nunca se convierten incluyen comas, guiones bajos, puntos y guiones.
and alphanumerics. All others are subject to conversion.
Ex:
>>> importar urllib
Hola Mundo@Python2
Hola Mundo@Python2
Al llamar a quote*(), la cadena theurldata se convierte en una cadena equivalente que puede ser
parte de una cadena de URL.
Ten en cuenta que la función quote() considera los caracteres seguros por defecto. Eso significa que no lo hace.
codificar / carácter .
La función quote() acepta un parámetro nombrado llamado safe cuyo valor predeterminado es/
Si también quieres codificar /carácter, puedes hacerlo proporcionando una cadena vacía
en el parámetro seguro así-
%2F
%2F‘
quote_plus() es similar a quote() excepto que también codifica espacios como signos más ( + ).
Ej:
>>> importar urllib
>>> [Link]('Hola Mundo@Python2')
Hola Mundo@Python2
[Link]()
urlencode() toma un diccionario de pares clave-valor y los codifica para ser incluidos como
parte de una consulta en una cadena de URL de solicitud CGI.
Los pares están en formato "clave=valor" y están delimitados por ampersands (&).
Ejemplo:
>>> aDict = { 'name': 'Georgina Garcia', 'hmdir': '~ggarcia' }
>>> [Link](aDict)
'name=Georgina+Garcia&hmdir=%7eggarcia'
Módulo urllib2:
urllib2 es un módulo de Python que se puede utilizar para obtener URLs.
galletas y más)
Diferencia entre urllib y urllib2
Aunque ambos módulos realizan tareas relacionadas con solicitudes URL, tienen funcionalidades diferentes.
urllib2 puede aceptar un objeto Request para establecer los encabezados de una solicitud URL, urllib
CGI (Interfaz de Puerta Común) es una tecnología y protocolo web que define una forma
para que un servidor web (servidor HTTP) interactúe con aplicaciones externas, por ejemplo, PHP.
CGI se utiliza como una interfaz entre el servidor web y el adicionalmente instalado
aplicaciones que generan contenido web dinámico. Estas aplicaciones se llaman scripts CGI
y están escritos en diferentes guiones y lenguajes de programación como PHP, Perl, Python,
etc.
CGI permite a los programas CGI procesar formularios HTML u otros datos que provienen de los clientes,
y luego permite que los programas CGI envíen una respuesta de vuelta al cliente
.
La respuesta puede ser documentos HTML, archivos GIF, clip de video o cualquier dato que el cliente
el navegador puede ver. Esto hace que tus páginas web sean interactivas con el usuario.
Cuando un cliente solicita un documento de un servidor, el servidor encuentra el archivo y se lo envía al
cliente.
Sin embargo, si un cliente solicita un programa CGI, el servidor simplemente actúa como un intermediario
1. El cliente envía una solicitud al servidor que se ejecuta en su máquina. La solicitud puede ser
para un documento, o como el contenido de un formulario HTML.
Si la solicitud es datos destinados a una aplicación externa, entonces el servidor necesita utilizar CGI
Por ejemplo, la solicitud del cliente podría ser buscar en una base de datos. La aplicación CGI
toma los criterios de búsqueda, busca en la base de datos y luego envía los resultados de vuelta al cliente.
2. Cuando un servidor recibe una solicitud que debe ser manejada por una aplicación externa
una solicitud (aCGI) que el servidor crea una copia de sí mismo.
El proceso CGI tiene todas las mismas rutas de comunicación que el proceso del servidor.
El programa CGI toma los datos que el servidor proporciona a través del entorno.
variables, entrada estándar o argumentos de línea de comandos.
Procesa los datos, contacta a los servicios externos que necesita y luego envía un
respuesta al servidor a través de las vías de datos utilizando la salida estándar.
Luego, el servidor toma la respuesta del programa y se la envía de vuelta al software del cliente.
Tu programa puede generar cualquier tipo de datos que necesite, incluyendo HTML, GIFs, o
JPEGs.
Aplicaciones CGI:
Las aplicaciones CGI que crean el HTML suelen estar escritas en uno de muchos lenguajes de programación de alto nivel.
lenguajes de programación de alto nivel que tienen la capacidad de aceptar datos del usuario, procesarlos y
un programa de computadora.
Cuando un script aCGI comienza, necesita recuperar los datos del formulario proporcionados por el usuario, pero él
debe obtener estos datos del cliente web, no de un usuario en la máquina del servidor ni de una
archivo de disco.
La salida difiere en que cualquier dato enviado a la salida estándar será enviado de vuelta a la conexión.
Los datos enviados de vuelta deben ser un conjunto de encabezados válidos seguidos de HTML. Si no es así, se produce un error.
ocurrirá porque los clientes web son un navegador, solo entienden datos HTTP válidos (es decir, MIME
encabezados y HTML).
Módulo cgi
Hay una clase principal en el módulo cgi, es decir, la clase FieldStorage.
Esta clase debe ser instanciada cuando un script CGI de Python comienza, ya que leerá todo el
información relevante del usuario desde el cliente web (a través del servidor web).
Una vez que este objeto ha sido instanciado, consistirá en un objeto similar a un diccionario que tiene
un conjunto de pares clave-valor. Las claves son los nombres de los elementos del formulario que se pasaron
a través del formulario mientras que los valores contienen los datos correspondientes.
Estos valores en sí mismos pueden ser uno de tres objetos. Pueden ser
Objetos FieldStorage (instancias)
MiniFieldStorage, que se utiliza en casos donde no hay subidas de archivos o formularios de múltiples partes
los datos están involucrados. Las instancias de MiniFieldStorage contienen solo el par clave-valor del nombre
y los datos.
Por último, pueden ser una lista de tales objetos. Esto ocurre cuando un formulario contiene más de
Para formularios web simples, generalmente encontrarás todas las instancias de MiniFieldStorage.
Construcción de aplicaciones CGI:
1. Configuración de un servidor web
Para trabajar con el desarrollo CGI en Python, primero necesitas instalar un servidor web.
Esto iniciará un servidor web en el puerto 8000 en tu máquina actual desde el actual
directorio. Luego puedes crear un Cgi-bin justo debajo del directorio desde el cual tú
inició el servidor y colocó sus scripts CGI de Python allí.
Coloca algunos archivos HTML en ese directorio y quizás algunos scripts CGI .py en Cgi-bin, y tú
están listos para "navegar" directamente a este sitio web con direcciones que se parecen a algo como esto:
[Link]
[Link]
2. Creando la Página del Formulario
Este archivo HTML ([Link]) presenta un formulario al usuario con un campo vacío para el
nombre del usuario y un conjunto de botones de radio para que el usuario elija.
1 <HTML><HEAD><TITLE> Como puedes ver en el código,
2 Amigos Demostración CGI (pantalla estática) el formulario contiene dos entradas
botón.
4. Sitios web totalmente interactivos:
Un usuario ingresa su información desde la página del formulario. Luego procesamos los datos y
salida de una página de resultados.
Ahora, añadiremos un enlace a la página de resultados que permitirá al usuario volver al formulario.
página, pero en lugar de presentar un formulario en blanco, llenaremos los datos que el usuario ha
ya proporcionado.
CGI Avanzado
Estos CGI avanzados incluyen el uso de cookies, datos en caché guardados en el lado del cliente.
multiple values for the same CGI field and file upload using multipart form submissions.
Using Cookies in CGI
Para un sitio web comercial, se requiere mantener la información de la sesión entre diferentes
páginas.
Por ejemplo, un registro de usuario termina después de completar muchas páginas. Cómo mantener
información de la sesión del usuario a través de todas las páginas web?
puede aceptar la cookie. Si lo hace, se almacena como un registro de texto plano en el disco duro del visitante
conducir.
Ahora, cuando el visitante llega a otra página en su sitio, la cookie está disponible para
recuperación. Una vez recuperado, su servidor sabe/recuerda lo que se almacenó.
Las cookies son un registro de datos en texto plano de 5 campos de longitud variable -
Caduca− La fecha en que la cookie expirará. Si está en blanco, la cookie expirará cuando el
el visitante cierra el navegador.
Name=Value− Cookies are set and retrieved in the form of key and value pairs.
Configuración de Cookies
Es muy fácil enviar cookies al navegador. Estas cookies se envían junto con HTTP.
Encabezado antes del campo Content-type. Suponiendo que deseas establecer UserID y Password como
galletas.
La configuración de las cookies se realiza de la siguiente manera −
Esto produce el siguiente resultado para las cookies establecidas por el script anterior -
User ID = XYZ
Password = XYZ123
File Upload:
Para subir un archivo, el formulario HTML debe tener el atributo enctype establecido en multipart/form-data.
Cada una de las casillas de verificación está etiquetada con el mismo nombre de campo, pero para diferenciarlas,
cada uno tendrá un valor diferente asociado con una casilla de verificación en particular.
Como sabes, los datos del usuario se envían al servidor en pares clave-valor durante
envío del formulario.
associated with thesame key. In these cases, rather than being given a single
Instancia MiniFieldStorage para tus datos, el módulo cgi creará una lista de tales.
instancias que iterarás para obtener los diferentes valores.
Servidores Web (HTTP):
Un servidor web HTTP no es más que un proceso que se está ejecutando en tu máquina y hace
exactamente dos cosas:
1- Escucha solicitudes http entrantes en una dirección de socket TCP específica (dirección IP
y un número de puerto)
2- Maneja esta solicitud y envía una respuesta de vuelta al usuario.
Módulo BaseHTTPServer.
El controlador es la parte del software que realiza la mayor parte de la "servidumbre web."
HEADsolicitudes.
requests. Tiene la capacidad de llamar a scripts CGI para realizar el procesamiento solicitado y
Module Descripción
1. BaseHTTPServer Proporciona las clases base del servidor web y del controlador base.
Mencioné anteriormente, primero un servidor web es un proceso que escucha las solicitudes entrantes en
Dirección TCP específica. La dirección TCP se identifica por una dirección IP y un número de puerto.
En segundo lugar, también se le debe indicar a un servidor web cómo manejar las solicitudes entrantes.
Estas solicitudes entrantes son manejadas por controladores especiales. Puedes pensar en una web
el servidor como un despachador, llega una solicitud, el servidor http inspecciona la solicitud y
httpd.serve_forever()
2- El manejador
[Link](('', PORT), Handler)
La dirección TCP se pasa como una tupla de (dirección IP, número de puerto)
Estamos pasando una cadena vacía como dirección IP, lo que significa que el servidor estará escuchando.
Handler es [Link]
PORTstores the value of 8080, then the server will be listening on incoming requests on
ese puerto.
Ahora tenemos un servidor HTTP que está escuchando en cualquier interfaz en el puerto 8080 esperando por