Módulo 2. Lección 2.
Diseño de interfaz
Enlace a las guías
Comparte tus conocimientos de
las clases y la librería PyQt.
Cualificaciones
¿Qué es un objeto?
¿Propiedad? ¿Método?
¿Qué es una clase?
¿Conocen clases de objetos ya
creados?
Cualificaciones
Una propiedad
es una variable dentro de un objeto.
Un método
es una función dentro de un objeto.
Es una tortuga
Cualificaciones
Objeto Clase del objeto
Propiedades + Métodos
Nuestro conocimiento sobre todos
estos objetos
¿En qué consiste una clase?
¿Cómo creamos una clase?
Cualificaciones
Creando clases
Para crear una clase, necesitamos hacer lo siguiente:
● listar las propiedades en el constructor que defina las
características de una instancia de la clase;
● listar los métodos para gestionar una instancia.
Nombre de la
class Application():
clase
Cualificaciones
Valor
def __init__(self, title_text):
Nombre de la
Valor
[Link]
propiedad =
Nombre del método
title_text
Acción con objeto y propiedades
def print_info (self): ¿Qué es un constructor?
Acción con objeto y propiedades
¿Qué es self?
Creando clases
Para crear una clase, necesitamos hacer lo siguiente:
● listar las propiedades en el constructor que defina las
características de una instancia de la clase;
● listar los métodos para gestionar una instancia.
Nombre de la
class Application():
clase
Una función
Cualificaciones
Valor constructora especial
def __init__(self, title_text): que crea una instancia
Nombre de la
Valor de una clase con
[Link]
propiedad = propiedades
Nombre del método específicas.
title_text
Acción con objeto y propiedades
def print_info (self):
Acción con objeto y propiedades __init_
Dos guiones bajos.
_
Creando clases
Para crear una clase, necesitamos hacer lo siguiente:
● listar las propiedades en el constructor que defina las
características de una instancia de la clase;
● listar los métodos para gestionar una instancia.
Nombre de la
class Application():
clase
Cualificaciones
self es un parámetro
Valor
def __init__(self, title_text): que indica el objeto al
Nombre de la
Valor cual se le aplica el
[Link]
propiedad = método.
Nombre del método
title_text [Link] es una
Acción con objeto y propiedades propiedad del objeto a
def print_info (self): la cual se le aplica el
Acción con objeto y propiedades método.
¿Qué es una aplicación de ventana?
¿En qué consiste?
Cualificaciones
Una aplicación de ventana
es un programa de computadora que interactúa con el
usuario a través de una interfaz gráfica.
Una aplicación de ventana estándar está compuesta de lo siguiente:
❏ una ventana principal,
❏ controles (widgets),
❏ ventanas adicionales (opcional).
Cualificaciones
Ventana principal
Ventana adicional
Widgets
¿Cómo creamos un app?
¿Qué widgets conocen?
Cualificaciones
PyQt5 ––
es una librería multiplataforma para crear
aplicaciones de ventana.
from [Link] import Qt
from [Link] import QApplication, QWidget, QPushButton, QLabel,
QVBoxLayout
Objeto Designación
Aplicación
Cualificaciones
QApplication
Ventana de aplicación
QWidget
Etiqueta
QLabel
Botón
QPushButton
Línea guía vertical
QVBoxLayout
from [Link] import Qt
from [Link] import QApplication, QWidget, QPushButton, QLabel,
QVBoxLayout
app = QApplication([])
main_win = QWidget()
main_win.setWindowTitle('Identificador de ganador')
button = QPushButton('Generar')
text = QLabel('Hacer clic para descubrir el ganador')
Cualificaciones
winner = QLabel('?')
line = QVBoxLayout()
[Link](text, alignment = [Link])
[Link](winner, alignment = [Link])
[Link](button, alignment = [Link])
main_win.setLayout(line)
Ejemplo de una aplicación
implementada anteriormente.
main_win.show()
app.exec_()
¿Qué es el procesamiento de
eventos?
¿Cómo procesamos los eventos del
ratón?
Cualificaciones
Procesamiento de eventos (clic de botones)
1. Describe acciones al hacer clic en un botón en una función de
proceso separada.
2. Utiliza un comando para enlazar la función y el widget.
def show_winner():
Cualificaciones
[Link](show_fun_ti LA FUNCIÓN ES DESCRITA
POR SEPARADO
tle)
NOMBRE DE LA FUNCIÓN DE PROCESO A
LA CUAL RESPONDE EL BOTÓN
Módulo 2. Lección 2. Diseño de interfaz de la aplicación
Lluvia de ideas:
Programación orientada a objetos
Estructura de la librería PyQt
La librería PyQt tiene una estructura jerárquica compleja.
Algunas clases tienen una clase ancestro compartida, así que sus
instancias tienen propiedades y métodos similares.
Para poder utilizar las herramientas de PyQt de forma significativa, vamos
a aprender más sobre la herencia en la programación orientada a
objetos.
QtCore QtWidgets ...
Lluvia de ideas
El módulo Qt: Los módulos QApplication,
QWidget, QLabel y
constantes y banderas QVBoxLayout:
que determinan cómo
luce la ventana widgets y cómo están
organizados
Clases y subclases
Si pensamos en ejemplos de clases de la vida real, vamos a descubrir que
algunas clases son “descendientes” de otras clases.
todos los botones son widgets
todos los gatos son animales
todos los escritorios son mesas
Lluvia de ideas
todos los cometas son cuerpos celestiales
todos los coches son vehículos
A
B
Herencia
La herencia de clase ayuda a transferir todas las habilidades escritas
anteriormente para una clase más general a otra clase más privada, la
clase heredera.
A Propiedade Propiedade B
s s
Métodos
Propiedade Métodos
+
Lluvia de ideas
s
Métodos
Clase heredera Superclase
A
La clase A está anidada
B
dentro de la clase B
Superclase y clase heredera
Si la superclase ya está escrita, entonces necesitaremos hacer lo
siguiente para crear una clase heredera:
● al crear el heredero, especificar el nombre de la superclase;
● añadir los métodos necesarios a la clase heredera;
Nombre del Nombre de la
heredero superclase
class Application( ):
Lluvia de ideas
Valor Opción en la cual no se
def __init__(self, ): introducen nuevas
Valor propiedades.
super().__init__( )
Nombre del método La clase heredera solo
def print_info (self): es suplementada con un
Acción con objetos y propiedades nuevo método.
Superclase y clase heredera
Si la superclase ya está escrita, entonces necesitaremos hacer lo
siguiente para crear una clase heredera:
● al crear el heredero, especificar el nombre de la superclase;
● añadir los métodos necesarios a la clase heredera;
Nombre del Nombre de la
heredero superclase
class Application( ):
Lluvia de ideas
Valor super se refiere a la
def __init__(self, ): superclase.
Valor
super().__init__( El constructor heredero
trabajar con un
Nombre del método
) constructor de
Acción con objetos y propiedades
superclase.
def print_info (self):
Superclase y clase heredera
Si la superclase ya está escrita, entonces necesitaremos hacer lo
siguiente para crear una clase heredera:
● al crear el heredero, especificar el nombre de la superclase;
● añadir los métodos necesarios a la clase heredera;
● crear un constructor heredero.
Nombre del Nombre de la
heredero superclase
class Application( ):
Lluvia de ideas
Valor Valor
def
Valor Opción en la cual se
__init__(self, , ): introducen las nuevas
Nueva
Valor propiedades.
super().__init__(
propiedad )
Nombre del El constructor adopta las
self.
método = propiedades de la
Acción con objetos y propiedades superclase y añade una
def print_info (self): nueva.
Creando clases
Ejemplo (para consola). Application y Mobile Application.
La clase Application almacena información sobre el nombre, el tamaño y
la descripción de la aplicación.
Vamos a crear una clase heredera llamada Mobile Application con un
nuevo método y propiedad.
class Application():
Lluvia de ideas
def __init__(self, title_text, description_text,
volume_num):
[Link] = title_text
[Link] = description_text
[Link] = volume_num
def print_info(self):
print('Aplicación', [Link])
print('Descripción:', [Link])
print('Tamaño de aplicación:', [Link])
class Application():
def __init__(self, title_text, desription_text, volume_num):
#...
def print_info(self):
#...
class MobileApplication(Application):
#constructor de la clase heredera con un nuevo campo
def __init__(self, title_text, desription_text, volume_num,
system_type_text):
super().__init__(title_text, desription_text, volume_num)
Lluvia de ideas
self.system_type = system_type_text
#nuevo método de la clase heredera
def setup_application(self):
print('Instalación de', self.system_type, 'la aplicación está
completa')
mobile_app = MobileApplication('Mis notas', 'Notas inteligentes y listas', 50,
'Android')
class Application():
def __init__(self, title_text, description_text, volume_num):
#...
def print_info(self):
#...
class MobileApplication(Application):
def __init__(self, title_text, desription_text, volume_num,
system_type_text):
#...
def setup_application(self):
Lluvia de ideas
#...
mobile_app = MobileApplication('Mis notas', 'Notas inteligentes y listas', 50,
'Android')
mobile_app.print_info()
mobile_app.setup_application()
Conclusiones:
1. La herencia de clases nos ayuda a transferir todas las
habilidades escritas para una clase más general a otra
clase más privada, la clase heredera.
2. Se describe lo siguiente en la clase heredera:
❏ un nuevo constructor (tomando prestadas las
propiedades de la superclase usando el método
Lluvia de ideas
super()),
❏ nuevas propiedades (en el constructor),
❏ nuevos métodos.
Módulo 2. Lección 2. Diseño de interfaz
Lluvia de ideas:
Diseño de interfaz
Veamos la tarea
Para completar la tarea, necesitaremos hacer lo siguiente:
● aprender nuevos widgets para crear cuadros de mensaje y
botones de radio;
● aprender cómo crear > 1 diseño y colocar widgets en él.
Lluvia de ideas
La aplicación “competición”
Paso 1. Crear los widgets necesarios.
Objeto Designación
Aplicación
QApplication
Ventana de aplicación
QWidget
Etiqueta
QLabel
Lluvia de ideas
Línea guía (vertical, horizontal)
QVBoxLayout, QHBoxLayout
Ventana de mensaje
QMessageBox()
Botón de radio
QRadioButton
¿Cómo importamos los módulos necesarios de la librería?
Importando módulos PyQt
QtCore QtWidgets ...
El módulo Qt: Los módulos QApplication,
QWidget, QLabel y
constantes y banderas QVBoxLayout:
que determinan cómo
luce la ventana widgets y cómo están
Lluvia de ideas
organizados
Se necesita importar del Necesita ser importada para los
parámetro alignment. widgets correspondientes.
from [Link] import Qt
from [Link] import (
QApplication, QWidget, QLabel, QVBoxLayout, QHBoxLayout, QMessageBox
)
Creando una aplicación y la ventana
principal
from [Link] import Qt
from [Link] import QApplication, QWidget, QPushButton, QLabel,
QVBoxLayout
app = QApplication([])
my_win = QWidget()
my_win.show()
Lluvia de ideas
app.exec_()
No olviden cambiar el tamaño de la
ventana y escoger dónde aparecerá.
Creando una pregunta y opciones de
respuestas
Opción de respuesta:
Método Propósito
Un constructor que crea un
btn_answer = QRadioButton('Firma')
objeto de tipo “Botón de radio”
con una firma.
Pregunta (ya conocen este widget):
Lluvia de ideas
Método Propósito
Un constructor que crea el
question = QLabel('¿Qué año?')
objeto de tipo “Etiqueta” con el
texto especificado.
Posicionando los widgets junto a la línea
Método Propósito
v_line = QVBoxLayout() Un constructor que crea un
objeto de tipo “línea vertical”.
v_line.addWidget( Un método que añade un widget a
title, alignment = la línea y la posiciona en el centro.
[Link]
)
Lluvia de ideas
Añade la línea resultante y sus
my_win.setLayout(v_line)
objetos a la ventana de la
aplicación.
from [Link] import Qt
from [Link] import QApplication, QWidget, QPushButton, QHBoxLayout, QVBoxLayout,
QLabel, QMessageBox, QRadioButton
app = QApplication([])
main_win = QWidget()
main_win.setWindowTitle('Competición de Crazy People')
question = QLabel('¿En qué año el canal recibió su “botón de reproducción dorado” de YouTube?')
btn_answer1 = QRadioButton('2005')
btn_answer2 = QRadioButton('2010')
btn_answer3 = QRadioButton('2015')
btn_answer4 = QRadioButton('2020')
Lluvia de ideas
layout_main = QVBoxLayout()
layout_main.addWidget(question, alignment = [Link])
layout_main.addWidget(btn_answer1, alignment = [Link])
layout_main.addWidget(btn_answer2, alignment = [Link])
layout_main.addWidget(btn_answer3, alignment = [Link])
layout_main.addWidget(btn_answer4, alignment = [Link])
main_win.setLayout(layout_main) La aplicación con una pregunta y cuatro
main_win.show() posibles respuestas.
app.exec_()
Posicionando los widgets usando diseños
Para posicionar los widgets como
quiere el cliente, se necesita hacer lo
siguiente:
❏ Crear tres líneas guía
horizontales.
❏ Añadir los widgets necesarios a
cada línea. Obtendremos tres
diseños con widgets.
Lluvia de ideas
❏ Añadir estos diseños a la línea
vertical principal.
❏ Unir el diseño principal (diseño
de la línea vertical) a la ventana
de aplicación.
Posicionando los widgets usando diseños
layoutH1 = QHBoxLayout()
layoutH2 = QHBoxLayout()
layoutH3 = QHBoxLayout()
Lluvia de ideas
Posicionando los widgets usando diseños
layoutH1 = QHBoxLayout()
layoutH2 = QHBoxLayout()
layoutH3 = QHBoxLayout()
[Link](question, alignment =
[Link])
[Link](btn_answer1, alignment =
[Link])
[Link](btn_answer2, alignment =
Lluvia de ideas
[Link])
[Link](btn_answer3, alignment =
[Link])
[Link](btn_answer4, alignment =
[Link])
Posicionando los widgets usando diseños
layoutH1 = QHBoxLayout()
layoutH2 = QHBoxLayout()
layoutH3 = QHBoxLayout()
[Link](question, alignment = [Link])
[Link](btn_answer1, alignment = [Link])
[Link](btn_answer2, alignment = [Link])
[Link](btn_answer3, alignment = [Link])
[Link](btn_answer4, alignment = [Link])
Lluvia de ideas
layout_main = QVBoxLayout()
layout_main.addLayout(layoutH1)
layout_main.addLayout(layoutH2)
layout_main.addLayout(layoutH3)
Posicionando los widgets usando diseños
layoutH1 = QHBoxLayout()
layoutH2 = QHBoxLayout()
layoutH3 = QHBoxLayout()
[Link](question, alignment = [Link])
[Link](btn_answer1, alignment = [Link])
[Link](btn_answer2, alignment = [Link])
[Link](btn_answer3, alignment = [Link])
[Link](btn_answer4, alignment = [Link])
Lluvia de ideas
layout_main = QVBoxLayout()
layout_main.addLayout(layoutH1)
layout_main.addLayout(layoutH2)
layout_main.addLayout(layoutH3)
main_win.setLayout(layout_main)
Creando una ventana de notificación
Una ventana con una etiqueta de notificación y un botón de “OK” preparado:
Método Propósito
Un constructor que crea una
victory_win = QMessageBox()
ventana de notificación.
victory_win.setText('Correct!') Un método que muestra el texto
específico en la ventana.
Lluvia de ideas
Deja abierta la ventana.
victory_win.exec_()
El botón se crea automáticamente.
Hacer clic en “OK” cierra la ventana.
Procesamiento de clic en los botones de
radio
Los clientes quieren que suceda lo siguiente:
❏ al hacer clic en el botón de radio correcto (“2005”), aparece una
ventana diciendo “¡Correcto! ¡Ganaste un scooter gyro!”
❏ al hacer clic en cualquier otro botón de radio, aparece una ventana
diciendo “No, fue en el 2005. Ganaste un póster de la empresa.”
Lluvia de ideas
¿Cómo programamos esto?
Procesamiento del clic del botón
Posible solución. Posible solución. Escribir dos funciones de proceso.
❏ el botón de radio correcto responde a la función de proceso que crea
una ventana con un mensaje sobre la victoria;
❏ los otros botones de radio responden a la función que crea una
ventana con la respuesta correcta.
def show_win():
Lluvia de ideas
btn_answer1.[Link](show_w LA FUNCIÓN ES DESCRITA
POR SEPARADO
in)
NOMBRE DE LA FUNCIÓN DE PROCESO A
LA CUAL RESPONDE EL BOTÓN
#...importando librerías
def show_win():
victory_win = QMessageBox()
victory_win.setText('¡Correcto!\nGanaste un scooter gyro')
victory_win.exec_()
def show_lose():
victory_win = QMessageBox()
victory_win.setText('No, fue en el 2015.\nGanaste un póster de la
empresa')
victory_win.exec_()
#...creando una aplicación y ventana principal
#...creando pregunta y widgets de respuesta
Lluvia de ideas
#...creando diseños y añadiendo widgets
btn_answer3.[Link](show_win)
btn_answer1.[Link](show_lose)
btn_answer2.[Link](show_lose)
btn_answer4.[Link](show_lose)
main_win.show()
app.exec_()
Conclusiones:
1. El widget QRadioButton es responsable por los
botones de radio y QMessageBox es responsable por
las ventanas de notificación.
2. Se pueden añadir varios widgets al mismo diseño y los
diseños pueden estar anidados entre ellos.
Lluvia de ideas