Curso de Brython en Español - Manejo de Eventos
Responder a eventos en aplicaciones Brython
En lo que llevamos de curso hemos visto cosas interesantes, pero todavía no tenemos la sensación de estar creando aplicaciones.
Hasta ahora, todo lo que hemos hecho podría haberse implementado solamente escribiendo un archivo html estático.
Ha llegado el momento de dotar de funcionalidad real a nuestras aplicaciones.
Crea un archivo index.html con el esqueleto básico para ejecutar brython (tal como vimos en el primer capítulo del curso), y ejecuta un servidor http local con python -m http.server
. Abre el navegador en la dirección http://localhost:8000
y refresca la página cada vez que apliques cambios en la app.
Lo primero que haremos será añadir un button
al documento. Podría declararse desde html pero vamos a hacerlo todo en brython:
from browser import document
from browser.html import *
boton = BUTTON('Haz Click y verás!')
document <= boton
Este script muestra un botón que no hace nada. A continuación veremos como hacer que suceda algo al hacer click en el botón.
Dar funcionalidad a un botón
Primero veremos cómo se harían las cosas en javascript (pero desde código brython). Posteriormente utilizaremos el estilo brython.
1 - Al estilo de javascript
Todos los elementos html tienen un atributo onclick
. El valor de este atributo debe ser una función que reciba un parámetro. Por convención, a este parámetro le llamaremos e
o ev
, ya que hace referencia al propio evento.
Por tanto, crearemos una función que reciba un parámetro y la asignaremos al atributo onclick
del botón:
from browser import document, alert
from browser.html import *
def mostrar_alerta(e):
alert('Has picado!! jajaja')
boton = BUTTON('Haz Click y verás!')
boton.onclick = mostrar_alerta
document <= boton
Dado que la función mostrar_alerta
se ejecuta en respuesta a un evento (en este caso, al evento click), se dice que esta función es un manejador de eventos (o controlador de eventos).
Ya que nuestro manejador de eventos es muy sencillo, vamos a expresarlo como una función lambda:
from browser import document, alert
from browser.html import *
boton = BUTTON('Haz Click y verás!')
boton.onclick = lambda e: alert('Has picado!! jajaja')
document <= boton
También puedes registrar un manejador de eventos utilizando addEventListener
:
from browser import document, alert
from browser.html import *
boton = BUTTON('Haz Click y verás!')
boton.addEventListener('click', lambda e: alert('Has picado!! jajaja'))
document <= boton
Puedes registrar varios manejadores para un mismo evento:
from browser import document, alert
from browser.html import *
boton = BUTTON('Haz Click y verás!')
boton.addEventListener('click', lambda e: alert('Has picado!! jajaja'))
boton.addEventListener('click', lambda e: alert('jajajaja me parto!!'))
document <= boton
2 - Al estilo de brython
En brython, para hacer que el código sea mas pythonico, los elementos además soportan el método bind
, que funciona exactamente igual que addEventListener
:
from browser import document, alert
from browser.html import *
boton = BUTTON('Haz Click y verás!')
boton.bind('click', lambda e: alert('Hola Dude!!'))
document <= boton
Este ha sido un ejemplo muy sencillo. Compliquemos un poco el manejador del evento click:
from browser import document
from browser.html import *
def add_elements(e):
if len(document.select('p')) == 0:
document <= P('El texto del botón era: ' + SPAN(e.target.text, style={'color':'red'}))
document <= P(STRONG(':)'))
e.target.text = f'Has hecho click {len(document.select("strong"))} veces'
boton = BUTTON('Haz Click y verás!')
boton.bind('click', add_elements)
document <= boton
Fíjate en que dentro de add_elements
estoy utilizando e.target
para referirme al disparador del evento, es decir, al elemento sobre el que se ha producido el evento (en este caso es el botón).
En cualquier momento pues desvincular un manejador de eventos utilizando en método unbind
:
from browser import document, alert
from browser.html import *
def add_elements(e):
n_parrafos = len(document.select('p'))
if n_parrafos == 0:
document <= P('El texto del botón era: ' + SPAN(e.target.text, style={'color':'red'}))
document <= P(STRONG(':)'))
n_strongs = len(document.select("strong"))
e.target.text = f'Has hecho click {n_strongs} veces'
if n_parrafos == 10:
e.target.unbind('click', add_elements)
e.target.bind('click', lambda e: alert('FIN'))
boton = BUTTON('Haz Click y verás!')
boton.bind('click', add_elements)
document <= boton
Puedes listar los manejadores asociados a un evento, sobre un elemento, utilizando el método events
:
from browser import document
from browser.html import *
def controlador(e):
click_events = e.target.events('click')
if len(click_events) > 5:
e.target.unbind('click')
e.target.bind('click', list_handlers)
div.clear()
def list_handlers(e):
btn.bind('click', controlador)
div.clear()
div <= UL([LI(str(i)[1:-1]) for i in e.target.events('click') if i != list_handlers])
btn = BUTTON('Click Me!')
div = DIV()
document <= btn + div
btn.bind('click', list_handlers)
En ocasiones definirás un manejador de eventos solamente para un elemento html. En estos casos puede que te interese utilizar browser.bind
como un decorador:
from browser import document, bind
from browser.html import *
boton = BUTTON('Haz Click y verás!')
@bind(boton, 'click')
def add_elements(e):
document <= P(f'document.body contiene {len(document.children)} elementos', style=dict(
color=('yellow' if len(document.children) % 2 else 'black'), backgroundColor=('black' if len(document.children) % 2 else 'yellow')
))
document <= boton
Aplicación de ejemplo (calculadora)
Hay muchos otros eventos que podemos manejar (por ejemplo la pulsación de teclas del teclado), pero eso lo veremos en otro capítulo.
Para dejarte con mas ganas de brython voy a mostrarte el código para crear una calculadora básica:
from browser import document, alert, window
from browser.html import *
document.select_one('title').text = 'Calculadora Básica'
document <= STYLE('''
*:not(button) {
margin: 0px;
padding: 0px;
border: 0px;
outline: none;
user-select: none;
}
body {
width: 100vw;
height: 100vh;
box-sizing: border-box;
}
input {
width: 100%;
text-align: center;
height:10%;
font-size: 1.5em;
}
table {
width: 100%;
height: 90%;
}
tr {
height: 25%;
}
button {
width: 100%;
height: 100%;
font-size:1.5em;
}
''')
textbox = INPUT(type='text', placeholder='0')
document <= textbox
botones = [
['7', '8', '9', '/'],
['4', '5', '6', '*'],
['1', '2', '3', '-'],
['0', '.', '=', '+']
]
document <= TABLE([TR([TD(BUTTON(celda)) for celda in fila]) for fila in botones])
def add_digit(e):
textbox.value += e.target.text
def calc_result(e):
try:
textbox.value = eval(textbox.value)
except Exception as e:
alert(f'ERROR:\n\n{e}')
textbox.value = '0'
for button in document.select('table > tr > td > button'):
if button.text != '=':
button.bind('click', add_digit)
else:
button.bind('click', calc_result)
El objetivo de este capítulo no es explicar cómo funciona esta calculadora. Realmente la mayor parte del código son los estilos css.
Espero que te hayas quedado con mas ganas de Brython !!
Atributos y métodos que debes conocer
Para obtener información mas detallada visita la web oficial de brython (eventos).
Métodos de
DOMElement
:- método
bind
- método
unbind
- método
events
- método
Atributos de
DOMEvent
:- atributo
bubbles
- atributo
cancelable
- atributo
currentTarget
- atributo
defaultPrevented
- atributo
eventPhase
- atributo
target
- atributo
timeStamp
- atributo
type
- atributo
Métodos de
DOMEvent
:- método
preventDefault
- método
stopPropagation
- método
Tipos de Eventos
Hay muchos otros eventos que puedes manejar además de click
: