Módulo 6

Módulo 6: Signals y Slots — Dando Vida a tu Diseño

Conecta elementos para que respondan a las acciones del usuario, sin programar

Conecta elementos para que respondan a las acciones del usuario, sin programar

---

Objetivos de Aprendizaje

Al finalizar este módulo serás capaz de:

  • Comprender qué son Signals y Slots y cómo funcionan
  • Usar el Signal/Slot Editor de Qt Designer para crear conexiones visuales
  • Conectar los signals y slots más comunes entre widgets
  • Crear interfaces interactivas sin escribir una sola línea de código
  • Entender el flujo de datos entre widgets conectados
  • Identificar qué conexiones son posibles y cuáles requieren código

---

6.1 ¿Qué son Signals y Slots?

Signals (señales) son eventos que un widget emite cuando algo sucede.

Slots (ranuras) son acciones que otro widget ejecuta como respuesta.

🎨 ANALOGÍA DEL DISEÑO

>

En diseño gráfico, cuando haces un prototipo interactivo en Figma, conectas un botón con una pantalla: "cuando el usuario hace clic aquí, muestra esta pantalla".

>

Signals y Slots son exactamente eso: "CUANDO pasa esto (signal), ENTONCES haz esto (slot)".

>

Ejemplo: "CUANDO el usuario hace clic en el botón (signal: clicked), ENTONCES cierra la ventana (slot: close)".

El concepto en una frase

CUANDO [widget A] hace [signal] → ENTONCES [widget B] ejecuta [slot]

Ejemplos cotidianos

CUANDO (Signal) ENTONCES (Slot) Resultado
----------------- ----------------- -----------
Usuario hace clic en botón (`clicked`) Ventana se cierra (`close`) El botón cierra la ventana
Usuario escribe en campo (`textChanged`) Label actualiza su texto (`setText`) El label muestra lo que escribes
Usuario mueve slider (`valueChanged`) Spin Box cambia valor (`setValue`) El spin box sigue al slider
Usuario marca checkbox (`toggled`) Frame se muestra/oculta (`setVisible`) El checkbox muestra/oculta contenido

💡 CONSEJO: Lo mejor es que puedes configurar Signals y Slots directamente en Qt Designer, sin escribir una sola línea de código.

---

6.2 El Signal/Slot Editor

En la parte inferior de Qt Designer hay una pestaña llamada "Signals & Slots Editor". Aquí defines las conexiones de forma visual.

Modo Edición de Signals/Slots (F4)

  1. Presiona F4 o haz clic en el botón "Edit Signals/Slots" en la toolbar
  2. El cursor cambia a una flecha con un rayo ⚡
  3. Haz clic en un widget (el que emite la señal) y arrastra hacia otro widget (el que responde)
  4. Aparecerá un diálogo donde seleccionas:
  • Signal: qué evento dispara la acción (clicked, textChanged, valueChanged, etc.)
  • Slot: qué acción se ejecuta (close, setText, hide, show, etc.)
  1. Haz clic en OK y la conexión queda creada
  2. Presiona F3 para volver al modo normal de edición

📸 [PLACEHOLDER PARA IMAGEN]: Captura de pantalla mostrando el modo F4 con una línea roja conectando un botón con un diálogo, y el diálogo de configuración de signal/slot.

Cómo ver las conexiones existentes

En modo F4, las conexiones se muestran como líneas rojas entre los widgets conectados. También puedes verlas en la pestaña "Signals & Slots Editor" en la parte inferior de la ventana.

Cómo eliminar una conexión

  1. Ve a la pestaña "Signals & Slots Editor" (parte inferior)
  2. Selecciona la conexión que quieres eliminar
  3. Presiona Delete o haz clic en el botón de eliminar

---

6.3 Conexiones Comunes sin Código

Estas son las conexiones más útiles que puedes hacer completamente en Qt Designer:

Cerrar ventana con botón

Origen Signal Destino Slot
-------- -------- --------- ------
Push Button `clicked()` Dialog / MainWindow `close()`

Resultado: Al hacer clic en el botón, la ventana se cierra.

Ocultar widget con botón

Origen Signal Destino Slot
-------- -------- --------- ------
Push Button `clicked()` Label / Frame / Widget `hide()`

Resultado: Al hacer clic, el widget desaparece.

Mostrar texto mientras escribes

Origen Signal Destino Slot
-------- -------- --------- ------
Line Edit `textChanged(QString)` Label `setText(QString)`

Resultado: El Label muestra en tiempo real lo que escribes en el Line Edit.

Slider sincronizado con Spin Box

Origen Signal Destino Slot
-------- -------- --------- ------
Slider `valueChanged(int)` Spin Box `setValue(int)`
Spin Box `valueChanged(int)` Slider `setValue(int)`

Resultado: El slider y el spin box se mantienen sincronizados. Mueve uno y el otro sigue.

Checkbox muestra/oculta contenido

Origen Signal Destino Slot
-------- -------- --------- ------
Check Box `toggled(bool)` Frame / Widget `setVisible(bool)`

Resultado: Cuando marcas el checkbox, el contenido aparece. Cuando lo desmarcas, desaparece.

Radio Button muestra/oculta sección

Origen Signal Destino Slot
-------- -------- --------- ------
Radio Button `toggled(bool)` Frame / Group Box `setVisible(bool)`

Resultado: Seleccionar un radio button muestra una sección específica.

Progreso controlado por slider

Origen Signal Destino Slot
-------- -------- --------- ------
Slider `valueChanged(int)` Progress Bar `setValue(int)`
Slider `valueChanged(int)` LCD Number `display(int)`

Resultado: El slider controla tanto la barra de progreso como el display numérico.

Cambiar pestaña con botón

Origen Signal Destino Slot
-------- -------- --------- ------
Push Button `clicked()` Tab Widget `setCurrentIndex(int)`

💡 CONSEJO: Para usar setCurrentIndex(int), necesitas editar la conexión y especificar el valor del índice manualmente. Qt Designer te pedirá el valor numérico.

---

6.4 Signals Más Útiles por Widget

Push Button

Signal Cuándo se dispara
-------- -------------------
`clicked()` Al hacer clic en el botón
`pressed()` Al presionar el botón (antes de soltar)
`released()` Al soltar el botón

Check Box

Signal Cuándo se dispara
-------- -------------------
`toggled(bool)` Al cambiar su estado (marcado/desmarcado)
`stateChanged(int)` Al cambiar su estado (con valor numérico: 0=desmarcado, 2=marcado)

Radio Button

Signal Cuándo se dispara
-------- -------------------
`toggled(bool)` Al cambiar su estado
`clicked()` Al hacer clic

Line Edit

Signal Cuándo se dispara
-------- -------------------
`textChanged(QString)` Cada vez que cambia el texto (mientras escribes)
`editingFinished()` Cuando terminas de editar (presionas Enter o pierdes el foco)
`returnPressed()` Cuando presionas Enter

Combo Box

Signal Cuándo se dispara
-------- -------------------
`currentIndexChanged(int)` Al cambiar la selección (por índice)
`currentTextChanged(QString)` Al cambiar la selección (por texto)
`activated(int)` Al seleccionar un item (incluso si ya estaba seleccionado)

Slider

Signal Cuándo se dispara
-------- -------------------
`valueChanged(int)` Al cambiar el valor
`sliderMoved(int)` Al arrastrar el slider (no al hacer clic en la barra)
`sliderPressed()` Al empezar a arrastrar
`sliderReleased()` Al soltar

Spin Box / Double Spin Box

Signal Cuándo se dispara
-------- -------------------
`valueChanged(int)` Al cambiar el valor
`valueChanged(double)` Al cambiar el valor (Double Spin Box)

Tab Widget

Signal Cuándo se dispara
-------- -------------------
`currentChanged(int)` Al cambiar de pestaña

Date Edit / Time Edit

Signal Cuándo se dispara
-------- -------------------
`dateChanged(QDate)` Al cambiar la fecha
`timeChanged(QTime)` Al cambiar la hora

Calendar Widget

Signal Cuándo se dispara
-------- -------------------
`selectionChanged()` Al seleccionar una fecha diferente
`clicked(QDate)` Al hacer clic en una fecha

---

6.5 Slots Más Útiles por Widget

Cualquier Widget

Slot Qué hace
------ ----------
`close()` Cierra la ventana/widget
`hide()` Oculta el widget
`show()` Muestra el widget (si estaba oculto)
`setEnabled(bool)` Activa/desactiva el widget
`setVisible(bool)` Muestra/oculta según el valor booleano

Label

Slot Qué hace
------ ----------
`setText(QString)` Cambia el texto del Label
`clear()` Limpia el texto del Label

Line Edit

Slot Qué hace
------ ----------
`setText(QString)` Cambia el texto del campo
`clear()` Limpia el campo

Text Edit / Plain Text Edit

Slot Qué hace
------ ----------
`setText(QString)` Cambia el texto
`clear()` Limpia el texto
`append(QString)` Agrega texto al final

Slider / Spin Box / Progress Bar

Slot Qué hace
------ ----------
`setValue(int)` Cambia el valor
`reset()` Reinicia al valor mínimo

LCD Number

Slot Qué hace
------ ----------
`display(int)` Muestra un número entero
`display(double)` Muestra un número decimal
`display(QString)` Muestra un texto

Combo Box

Slot Qué hace
------ ----------
`setCurrentIndex(int)` Selecciona un item por índice
`clear()` Elimina todos los items

---

6.6 Tipos de Datos en Signals y Slots

Para que una conexión funcione, los tipos de datos del signal y el slot deben ser compatibles:

Tipo de dato Descripción Ejemplo de uso
-------------- ------------- ----------------
**Sin tipo** `()` No lleva datos `clicked()`, `close()`
**bool** Verdadero o falso `toggled(bool)` → `setVisible(bool)`
**int** Número entero `valueChanged(int)` → `setValue(int)`
**QString** Texto `textChanged(QString)` → `setText(QString)`
**double** Número decimal `valueChanged(double)` → `display(double)`

⚠️ IMPORTANTE

>

No puedes conectar un signal que envía un tipo de dato con un slot que espera otro tipo diferente. Por ejemplo, no puedes conectar textChanged(QString) con setValue(int) directamente.

---

6.7 Conexiones en el Signals & Slots Editor

Además del modo visual (F4), puedes usar la pestaña Signals & Slots Editor en la parte inferior:

Columna Descripción
--------- -------------
**Sender** El widget que emite la señal
**Signal** La señal que emite
**Receiver** El widget que recibe la señal
**Slot** La acción que ejecuta

Cómo agregar una conexión desde el editor

  1. Haz clic en el botón "+" del Signals & Slots Editor
  2. Selecciona el Sender (widget origen)
  3. Selecciona el Signal
  4. Selecciona el Receiver (widget destino)
  5. Selecciona el Slot
  6. Haz clic en OK

---

6.8 Editar Conexiones con Valores Personalizados

Algunos slots requieren un valor específico. Por ejemplo, setCurrentIndex(int) necesita saber qué índice establecer.

Cómo editar una conexión existente

  1. En el Signals & Slots Editor, haz doble clic en la conexión
  2. O haz clic derecho > Edit
  3. En el diálogo, puedes:
  • Cambiar el signal
  • Cambiar el slot
  • Editar el valor del argumento (para slots que requieren un valor específico)

Ejemplo: Botón que cambia a la pestaña 2

  1. Conecta: Push Button (clicked()) → Tab Widget
  2. En el slot, selecciona setCurrentIndex(int)
  3. Qt Designer te pedirá el valor: ingresa 1 (los índices empiezan en 0, así que 1 = segunda pestaña)

---

6.9 Limitaciones de Signals/Slots en Qt Designer

No todas las conexiones son posibles sin código. Estas son las limitaciones:

Lo que SÍ puedes hacer Lo que NO puedes hacer sin código
------------------------ -----------------------------------
Conectar signals existentes a slots existentes Crear signals o slots personalizados
Pasar valores simples (int, bool, QString) Ejecutar lógica compleja (cálculos, condiciones)
Mostrar/ocultar widgets Validar datos de entrada
Cambiar texto de widgets Guardar datos en archivos o bases de datos
Cambiar valores numéricos Hacer peticiones a internet
Cerrar ventanas Abrir otras ventanas

💡 CONSEJO: Para funcionalidad avanzada, necesitarás código Python. Pero el 80% de las interacciones básicas se pueden configurar sin código en Qt Designer.

---

6.10 Flujo de Datos Visual

Así es como funciona el flujo de datos entre widgets conectados:

Usuario escribe "Hola" en Line Edit
         │
         ▼
Line Edit emite: textChanged("Hola")
         │
         ▼ (conexión configurada)
Label recibe: setText("Hola")
         │
         ▼
Label muestra: "Hola"
Usuario mueve Slider a valor 75
         │
         ▼
Slider emite: valueChanged(75)
         │
         ▼ (conexión configurada)
Progress Bar recibe: setValue(75)
         │
         ▼
Progress Bar muestra: 75%

---

Ejercicio Práctico del Módulo

🏋️ EJERCICIO 6: Mini Aplicación Interactiva sin Código

>

Objetivo: Crear una interfaz completamente interactiva usando solo Signals y Slots de Qt Designer.

>

Pasos:

1. Crea un Dialog sin botones de 500x400 píxeles

2. Cambia el windowTitle a "Demo Interactiva"

3. Cambia el fondo: styleSheet: background-color: #1a1a2e;

4. Agrega un Label de título: "Escribe algo:" (fuente 16pt, blanco)

5. Agrega un Line Edit con placeholder "Escribe algo aquí..."

6. Agrega un Label debajo con texto "Tu texto aparecerá aquí" (fuente 14pt, color verde, centrado)

7. Conecta: Line Edit (textChanged) → Label (setText)

8. Agrega un Label con texto "Control de volumen:"

9. Agrega un Horizontal Slider (min: 0, max: 100, value: 50)

10. Agrega un Spin Box al lado del slider (min: 0, max: 100, value: 50)

11. Agrega un Progress Bar debajo (min: 0, max: 100, value: 50, textVisible: true)

12. Agrega un LCD Number al lado del Progress Bar (digitCount: 3, value: 50)

13. Conecta: Slider (valueChanged) → Spin Box (setValue)

14. Conecta: Spin Box (valueChanged) → Slider (setValue)

15. Conecta: Slider (valueChanged) → Progress Bar (setValue)

16. Conecta: Slider (valueChanged) → LCD Number (display)

17. Agrega un Check Box con texto "Mostrar controles avanzados"

18. Agrega un Frame con un Dial y un Double Spin Box dentro (controles avanzados)

19. Conecta: Check Box (toggled) → Frame (setVisible)

20. Agrega un Push Button con texto "Cerrar" (estilizado en rojo)

21. Conecta: Button (clicked) → Dialog (close)

22. Renombra todos los widgets

23. Guarda como demo_interactiva.ui

24. Presiona Ctrl+R y prueba TODAS las interacciones

>

Resultado esperado: Una interfaz donde todo responde al usuario: el texto se replica, el slider controla múltiples widgets, el checkbox muestra/oculta contenido, y el botón cierra la ventana. Todo sin una sola línea de código.

---

Recursos Adicionales

Recurso Descripción
--------- -------------
[Signals and Slots](https://doc.qt.io/qt-6/signalsandslots.html) Documentación oficial
[Qt Designer Signals/Slots](https://doc.qt.io/qt-6/designer-connection.html) Cómo usar signals/slots en Qt Designer
[Qt Signals and Slots Tutorial](https://doc.qt.io/qt-6/signalsandslots-tutorial.html) Tutorial paso a paso

---

Evaluación de Comprensión

  1. ¿Qué es un Signal y qué es un Slot? Explica con tus propias palabras.
  2. ¿Cómo entras al modo de edición de Signals/Slots en Qt Designer?
  3. ¿Qué connection harías para que un botón cierre la ventana?
  4. ¿Qué signal del Line Edit se dispara mientras escribes (no al terminar)?
  5. ¿Cómo sincronizas un Slider con un Spin Box para que se muevan juntos?
  6. ¿Qué slot usarías para ocultar un Frame cuando se desmarca un Check Box?
  7. ¿Por qué no puedes conectar textChanged(QString) con setValue(int)?
  8. ¿Qué significa que un slot requiere un valor como setCurrentIndex(1)?
  9. ¿Dónde puedes ver todas las conexiones que has creado?
  10. ¿Qué limitaciones tienen los Signals/Slots configurados en Qt Designer?

---

Módulo anterior: ← [Módulo 5: Layouts](04-layouts.md)

Siguiente módulo: → [Módulo 7: Propiedades Avanzadas](06-propiedades-avanzadas.md)

📝 Evaluación de Comprensión

Escribe tus respuestas y luego presiona el botón para comparar con las respuestas correctas.

1. ¿Qué es un Signal y qué es un Slot? Explica con tus propias palabras.
✅ Respuesta Correcta
Un Signal es un evento que un widget emite cuando algo sucede (como hacer clic en un botón). Un Slot es una acción que otro widget ejecuta como respuesta al signal. Es el patrón 'CUANDO pasa esto, ENTONCES haz esto'.
2. ¿Cómo entras al modo de edición de Signals/Slots en Qt Designer?
✅ Respuesta Correcta
Presionando F4 o haciendo clic en el botón 'Edit Signals/Slots' en la toolbar.
3. ¿Qué conexión harías para que un botón cierre la ventana?
✅ Respuesta Correcta
Push Button (signal: clicked) → Dialog/MainWindow (slot: close).
4. ¿Qué signal del Line Edit se dispara mientras escribes (no al terminar)?
✅ Respuesta Correcta
textChanged(QString)
5. ¿Cómo sincronizas un Slider con un Spin Box para que se muevan juntos?
✅ Respuesta Correcta
Creando dos conexiones bidireccionales: Slider (valueChanged) → Spin Box (setValue) Y Spin Box (valueChanged) → Slider (setValue).
6. ¿Qué slot usarías para ocultar un Frame cuando se desmarca un Check Box?
✅ Respuesta Correcta
setVisible(bool), conectado desde el signal toggled(bool) del Check Box.
7. ¿Por qué no puedes conectar textChanged(QString) con setValue(int)?
✅ Respuesta Correcta
Porque los tipos de datos no son compatibles: textChanged envía un QString (texto) y setValue espera un int (número entero). Los tipos de datos del signal y el slot deben coincidir.
8. ¿Qué significa que un slot requiere un valor como setCurrentIndex(1)?
✅ Respuesta Correcta
Significa que el slot necesita un argumento específico para funcionar. En este caso, setCurrentIndex necesita saber qué índice establecer (1 = segunda pestaña, ya que los índices empiezan en 0).
9. ¿Dónde puedes ver todas las conexiones que has creado?
✅ Respuesta Correcta
En la pestaña 'Signals & Slots Editor' en la parte inferior de Qt Designer, y en modo F4 se muestran como líneas rojas entre los widgets conectados.
10. ¿Qué limitaciones tienen los Signals/Slots configurados en Qt Designer?
✅ Respuesta Correcta
No puedes crear signals o slots personalizados, ejecutar lógica compleja (cálculos, condiciones), validar datos, guardar en archivos/bases de datos, hacer peticiones a internet, ni abrir otras ventanas. Solo puedes conectar signals existentes a slots existentes con valores simples.
🏋️ Ejercicio Práctico

Ejercicio 6: Mini Aplicación Interactiva sin Código

Módulo 6: Signals y Slots

---

Objetivo

Crear una interfaz completamente interactiva usando solo Signals y Slots de Qt Designer.

---

Instrucciones

  1. Crea un Dialog sin botones de 500x400 píxeles
  2. windowTitle: "Demo Interactiva"
  3. Fondo: styleSheet: background-color: #1a1a2e;
  4. Label título: "Escribe algo:" (16pt, blanco)
  5. Line Edit con placeholder "Escribe algo aquí..."
  6. Label debajo con texto "Tu texto aparecerá aquí" (14pt, verde, centrado)
  7. Conecta (F4): Line Edit (textChanged) → Label (setText)
  8. Label: "Control de volumen:"
  9. Horizontal Slider (min: 0, max: 100, value: 50)
  10. Spin Box al lado del slider (min: 0, max: 100, value: 50)
  11. Progress Bar debajo (min: 0, max: 100, value: 50, textVisible: true)
  12. LCD Number al lado del Progress Bar (digitCount: 3, value: 50)
  13. Conecta: Slider (valueChanged) → Spin Box (setValue)
  14. Conecta: Spin Box (valueChanged) → Slider (setValue)
  15. Conecta: Slider (valueChanged) → Progress Bar (setValue)
  16. Conecta: Slider (valueChanged) → LCD Number (display)
  17. Check Box: "Mostrar controles avanzados"
  18. Frame con un Dial y un Double Spin Box dentro
  19. Conecta: Check Box (toggled) → Frame (setVisible)
  20. Push Button "Cerrar" (estilizado en rojo)
  21. Conecta: Button (clicked) → Dialog (close)
  22. Renombra todos los widgets
  23. Guarda como demo_interactiva.ui
  24. Presiona Ctrl+R y prueba TODAS las interacciones

---

Resultado Esperado

Una interfaz donde todo responde al usuario: el texto se replica en el label, el slider controla el spin box, progress bar y LCD number simultáneamente, el checkbox muestra/oculta el frame con controles avanzados, y el botón cierra la ventana. Todo sin código.

---

Checklist

  • [ ] Line Edit → Label (text se replica en tiempo real)
  • [ ] Slider ↔ Spin Box (sincronizados bidireccionalmente)
  • [ ] Slider → Progress Bar (muestra el valor)
  • [ ] Slider → LCD Number (muestra el valor)
  • [ ] Check Box → Frame (muestra/oculta controles avanzados)
  • [ ] Botón Cerrar → Dialog (cierra la ventana)
  • [ ] Todas las conexiones visibles en modo F4