Módulo 11: Formularios Completos
Aplica todo lo aprendido para crear formularios profesionales y funcionales
Aplica todo lo aprendido para crear formularios profesionales y funcionales
---
Objetivos de Aprendizaje
Al finalizar este módulo serás capaz de:
- Aplicar principios de diseño UX a formularios
- Identificar y aplicar patrones comunes de formularios
- Crear formularios de registro, contacto, configuración y wizard
- Agrupar campos lógicamente con Group Boxes
- Validar visualmente campos obligatorios
- Crear formularios responsivos que se adaptan a cualquier tamaño
- Aplicar estilos coherentes a formularios completos
---
11.1 Anatomía de un Buen Formulario
Un buen formulario sigue principios de diseño UX que ya conoces como diseñador:
Principios Fundamentales
| Principio | Descripción | Cómo aplicarlo en Qt Designer |
|---|---|---|
| ----------- | ------------- | ------------------------------- |
| **Jerarquía visual** | Los campos más importantes son más prominentes | Usa fuentes más grandes para títulos, colores para destacar |
| **Agrupación lógica** | Campos relacionados van juntos | Usa Group Boxes para cada sección |
| **Espacio en blanco** | Dale respiro a los elementos | Usa Layouts con márgenes adecuados |
| **Feedback visual** | El usuario debe saber qué está pasando | Usa placeholders, tooltips, labels claros |
| **Consistencia** | Mismo estilo para elementos del mismo tipo | Define estilos globales en el styleSheet del padre |
| **Accesibilidad** | Todos pueden usar el formulario | Contrastes adecuados, tamaño de fuente legible, labels claros |
Flujo visual de un formulario
┌─────────────────────────────────────┐
│ TÍTULO DEL FORMULARIO │ ← Grande, llamativo
├─────────────────────────────────────┤
│ │
│ ┌─ Sección 1 ──────────────────┐ │ ← Group Box
│ │ Campo 1: [___________] │ │
│ │ Campo 2: [___________] │ │
│ │ Campo 3: [▼ Seleccionar] │ │
│ └──────────────────────────────┘ │
│ │
│ ┌─ Sección 2 ──────────────────┐ │ ← Group Box
│ │ Campo 4: [___________] │ │
│ │ Campo 5: [___________] │ │
│ └──────────────────────────────┘ │
│ │
│ ┌─ Sección 3 ──────────────────┐ │ ← Group Box
│ │ ☐ Opción A │ │
│ │ ☐ Opción B │ │
│ │ Nivel: ━━━●━━━ 7 │ │
│ └──────────────────────────────┘ │
│ │
│ [Cancelar] [Enviar] │ ← Botones alineados a la derecha
└─────────────────────────────────────┘
---
11.2 Patrones Comunes de Formularios
Patrón 1: Formulario de Registro
Propósito: Recopilar información de un nuevo usuario.
┌─────────────────────────────────────┐
│ REGISTRO DE USUARIO │
├─────────────────────────────────────┤
│ │
│ ┌─ Datos de la cuenta ─────────┐ │
│ │ Email: [___________] │ │
│ │ Contraseña: [••••••••••] │ │
│ │ Confirmar: [••••••••••] │ │
│ └──────────────────────────────┘ │
│ │
│ ┌─ Datos personales ───────────┐ │
│ │ Nombre: [___________] │ │
│ │ Apellidos: [___________] │ │
│ │ Fecha nac.: [__/__/____] │ │
│ │ Género: ○ M ○ F ○ Otro │ │
│ └──────────────────────────────┘ │
│ │
│ ☐ Acepto los términos y condiciones│
│ ☐ Quiero recibir el newsletter │
│ │
│ [Cancelar] [Registrarse]│
└─────────────────────────────────────┘
Widgets clave:
- Line Edit (con echoMode: Password para contraseñas)
- Date Edit (para fecha de nacimiento)
- Radio Buttons (para género)
- Check Boxes (para aceptación de términos)
- Push Buttons (Cancelar y Registrarse)
---
Patrón 2: Formulario de Contacto
Propósito: Permitir que el usuario envíe un mensaje.
┌─────────────────────────────────────┐
│ CONTÁCTANOS │
├─────────────────────────────────────┤
│ │
│ Nombre: [_________________] │
│ Email: [_________________] │
│ Asunto: [▼ Selecciona... ] │
│ │
│ Mensaje: │
│ ┌──────────────────────────────┐ │
│ │ │ │
│ │ Escribe tu mensaje aquí... │ │
│ │ │ │
│ │ │ │
│ └──────────────────────────────┘ │
│ │
│ ☐ Deseo recibir respuestas por email│
│ │
│ [Cancelar] [Enviar] │
└─────────────────────────────────────┘
Widgets clave:
- Line Edit (nombre, email)
- Combo Box (asunto con opciones predefinidas)
- Text Edit o Plain Text Edit (mensaje)
- Check Box (preferencia de respuesta)
---
Patrón 3: Formulario de Configuración
Propósito: Permitir al usuario personalizar la aplicación.
┌─────────────────────────────────────┐
│ [General] [Apariencia] [Avanzado] │
├─────────────────────────────────────┤
│ │
│ ┌─ General ────────────────────┐ │
│ │ Idioma: [▼ Español ] │ │
│ │ Zona hor.: [▼ GMT-6 ] │ │
│ │ ☐ Iniciar con el sistema │ │
│ │ ☐ Guardar sesión al salir │ │
│ └──────────────────────────────┘ │
│ │
│ ┌─ Notificaciones ─────────────┐ │
│ │ ☐ Notificaciones por email │ │
│ │ ☐ Notificaciones push │ │
│ │ Frecuencia: [▼ Diaria ] │ │
│ └──────────────────────────────┘ │
│ │
│ [Restaurar] [Aplicar] [OK] │
└─────────────────────────────────────┘
Widgets clave:
- Tab Widget (para categorías)
- Group Boxes (para secciones dentro de cada pestaña)
- Combo Boxes (selectores)
- Check Boxes (opciones booleanas)
- Botones: Restaurar, Aplicar, OK, Cancelar
---
Patrón 4: Formulario Wizard (Asistente)
Propósito: Guiar al usuario paso a paso por un proceso complejo.
Paso 1: Bienvenida
┌─────────────────────────────────────┐
│ ASISTENTE DE INSTALACIÓN │
├─────────────────────────────────────┤
│ │
│ ¡Bienvenido! │
│ │
│ Este asistente te guiará por el │
│ proceso de instalación paso a paso.│
│ │
│ Se necesitan aproximadamente 5 min.│
│ │
│ [Siguiente >] │
└─────────────────────────────────────┘
Paso 2: Datos
┌─────────────────────────────────────┐
│ ASISTENTE DE INSTALACIÓN │
├─────────────────────────────────────┤
│ │
│ ┌─ Información personal ────────┐ │
│ │ Nombre: [______________] │ │
│ │ Empresa: [______________] │ │
│ │ Email: [______________] │ │
│ └───────────────────────────────┘ │
│ │
│ [< Anterior] [Siguiente >] │
└─────────────────────────────────────┘
Paso 3: Confirmación
┌─────────────────────────────────────┐
│ ASISTENTE DE INSTALACIÓN │
├─────────────────────────────────────┤
│ │
│ Resumen de tu configuración: │
│ │
│ Nombre: Juan Pérez │
│ Empresa: Mi Empresa S.A. │
│ Email: juan@email.com │
│ Plan: Profesional │
│ │
│ ¿Es correcto? │
│ │
│ [< Anterior] [Finalizar] │
└─────────────────────────────────────┘
Widgets clave:
- Stacked Widget (una página por paso)
- Botones de navegación (Anterior, Siguiente, Finalizar)
- Progress Bar (opcional, para indicar progreso)
- Labels de resumen en el paso final
---
11.3 Campos Obligatorios vs. Opcionales
Cómo marcar campos obligatorios
| Método | Descripción | Implementación |
|---|---|---|
| -------- | ------------- | ---------------- |
| **Asterisco (*)** | El más común y reconocido | Agrega `*` al texto del Label: `Nombre:*` |
| **Color del Label** | Labels obligatorios en un color diferente | styleSheet del Label: `color: #FF6B6B;` |
| **Borde del campo** | Borde rojo en campos obligatorios vacíos | styleSheet del Line Edit: `border: 2px solid #FF6B6B;` |
| **Leyenda** | Explicación al inicio del formulario | Label: "Los campos con * son obligatorios" |
Ejemplo de campo obligatorio
/* Label obligatorio */
QLabel#nombre_label {
color: #e0e0e0;
}
QLabel#nombre_label::after {
/* Qt no soporta ::after, usa texto con asterisco */
}
/* Campo obligatorio con borde rojo (cuando está vacío) */
QLineEdit#nombre_input[required="true"] {
border: 2px solid #FF6B6B;
}
/* Campo válido */
QLineEdit#nombre_input:valid {
border: 2px solid #41CD52;
}
💡 CONSEJO: La forma más simple y efectiva es agregar un asterisco () al texto del Label y una leyenda al inicio del formulario: "Los campos marcados con son obligatorios".
---
11.4 Placeholders y Tooltips
Placeholders efectivos
Un buen placeholder da contexto sobre qué debe escribir el usuario:
| Campo | Mal placeholder | Buen placeholder |
|---|---|---|
| ------- | ----------------- | ------------------ |
| Nombre | "Texto" | "Escribe tu nombre completo" |
| "Email" | "tu@email.com" | |
| Teléfono | "Teléfono" | "+52 55 1234 5678" |
| Contraseña | "Contraseña" | "Mínimo 8 caracteres" |
| Búsqueda | "Buscar" | "Buscar por nombre, email o ID..." |
| Mensaje | "Mensaje" | "Describe tu consulta en detalle..." |
Tooltips útiles
| Widget | Tooltip | Por qué |
|---|---|---|
| -------- | --------- | --------- |
| Botón con solo icono | "Guardar (Ctrl+S)" | Explica la acción y el atajo |
| Campo de contraseña | "Mínimo 8 caracteres, una mayúscula y un número" | Indica los requisitos |
| Campo de email | "Usaremos este email para contactarte" | Explica el propósito |
| Check Box | "Recibirás un email semanal con novedades" | Explica qué implica marcarlo |
---
11.5 Validación Visual en Qt Designer
Aunque la validación real se hace con código, puedes preparar la validación visual en Qt Designer:
Input Masks
Los input masks restringen el formato de entrada:
| Máscara | Descripción | Ejemplo |
|---|---|---|
| --------- | ------------- | --------- |
| `000-000-0000` | Teléfono con guiones | `555-123-4567` |
| `00/00/0000` | Fecha con barras | `25/12/2024` |
| `>AAAAA-AAAAA-AAAAA-AAAAA-AAAAA` | Código de 25 caracteres en mayúsculas | `ABCDE-FGHIJ-KLMNO-PQRST-UVWXY` |
| `999.999.999.999;_` | Dirección IP (los dígitos son opcionales) | `192.168.1.1` |
| `#999` | Número con signo opcional | `+123`, `-45`, `67` |
Propiedades de validación
| Propiedad | Widget | Descripción |
|---|---|---|
| ----------- | -------- | ------------- |
| **maxLength** | Line Edit | Máximo número de caracteres |
| **inputMask** | Line Edit | Formato obligatorio de entrada |
| **minimum / maximum** | Spin Box, Date Edit | Rango de valores permitidos |
| **validator** | Line Edit | Validador personalizado (requiere código) |
---
11.6 Estilos para Formularios
Tema completo para formularios
/* === TEMA DE FORMULARIO === */
/* Fondo del diálogo */
QDialog {
background-color: #1a1a2e;
color: #e0e0e0;
font-family: "Segoe UI", sans-serif;
font-size: 13px;
}
/* Título del formulario */
QLabel#titulo_form {
font-size: 22px;
font-weight: bold;
color: #ffffff;
padding: 10px 0;
}
/* Labels de campos */
QLabel {
color: #ccc;
font-size: 13px;
}
/* Labels de campos obligatorios */
QLabel.obligatorio {
color: #FF6B6B;
}
/* Campos de entrada */
QLineEdit, QComboBox, QSpinBox, QDoubleSpinBox, QDateEdit {
background-color: #2d2d3d;
color: #ffffff;
border: 2px solid #444;
border-radius: 6px;
padding: 8px 12px;
min-height: 20px;
}
QLineEdit:focus, QComboBox:focus, QSpinBox:focus {
border-color: #41CD52;
}
QLineEdit:hover, QComboBox:hover {
border-color: #666;
}
/* Áreas de texto */
QPlainTextEdit, QTextEdit {
background-color: #2d2d3d;
color: #ffffff;
border: 2px solid #444;
border-radius: 6px;
padding: 8px 12px;
}
QPlainTextEdit:focus, QTextEdit:focus {
border-color: #41CD52;
}
/* Group Boxes */
QGroupBox {
border: 1px solid #444;
border-radius: 8px;
margin-top: 12px;
padding-top: 15px;
font-weight: bold;
color: #41CD52;
font-size: 14px;
}
QGroupBox::title {
subcontrol-origin: margin;
left: 12px;
padding: 0 8px;
}
/* Combo Box */
QComboBox {
background-color: #2d2d3d;
color: #ffffff;
border: 2px solid #444;
border-radius: 6px;
padding: 6px 12px;
}
QComboBox::drop-down {
border: none;
width: 24px;
}
QComboBox QAbstractItemView {
background-color: #2d2d3d;
color: #ffffff;
selection-background-color: #41CD52;
selection-color: #1a1a2e;
}
/* Check Boxes y Radio Buttons */
QCheckBox, QRadioButton {
color: #e0e0e0;
spacing: 8px;
padding: 4px 0;
}
QCheckBox::indicator, QRadioButton::indicator {
width: 18px;
height: 18px;
border: 2px solid #444;
background-color: #2d2d3d;
}
QCheckBox::indicator {
border-radius: 4px;
}
QRadioButton::indicator {
border-radius: 9px;
}
QCheckBox::indicator:checked, QRadioButton::indicator:checked {
background-color: #41CD52;
border-color: #41CD52;
}
QCheckBox::indicator:hover, QRadioButton::indicator:hover {
border-color: #41CD52;
}
/* Sliders */
QSlider::groove:horizontal {
background: #444;
height: 6px;
border-radius: 3px;
}
QSlider::handle:horizontal {
background: #41CD52;
width: 18px;
margin: -6px 0;
border-radius: 9px;
}
QSlider::sub-page:horizontal {
background: #41CD52;
border-radius: 3px;
}
/* Botones */
QPushButton {
background-color: #41CD52;
color: #1a1a2e;
border: none;
padding: 10px 24px;
border-radius: 8px;
font-weight: bold;
font-size: 13px;
min-width: 100px;
}
QPushButton:hover {
background-color: #2D9B3E;
}
QPushButton:pressed {
background-color: #1a7a2e;
}
QPushButton#cancelar_btn {
background-color: #555;
color: #ccc;
}
QPushButton#cancelar_btn:hover {
background-color: #666;
}
/* Tab Widget */
QTabWidget::pane {
border: 1px solid #444;
border-radius: 6px;
background: #1a1a2e;
}
QTabBar::tab {
background: #2d2d3d;
color: #888;
padding: 8px 16px;
border-top-left-radius: 6px;
border-top-right-radius: 6px;
margin-right: 2px;
}
QTabBar::tab:selected {
background: #1a1a2e;
color: #41CD52;
}
QTabBar::tab:hover:!selected {
background: #222240;
color: #ccc;
}
---
11.7 Errores Comunes en Formularios
| Error | Problema | Solución |
|---|---|---|
| ------- | ---------- | ---------- |
| **Demasiados campos** | El usuario se siente abrumado | Divide en pasos o pestañas |
| **Campos sin label claro** | El usuario no sabe qué escribir | Labels descriptivos + placeholders |
| **Sin agrupación lógica** | Todo se ve como una lista interminable | Usa Group Boxes para secciones |
| **Botones poco claros** | El usuario no sabe qué hace cada botón | Textos descriptivos: "Guardar cambios" en lugar de "OK" |
| **Sin validación visual** | El usuario envía datos incorrectos | Input masks, maxLength, placeholders informativos |
| **Orden de tabulación incorrecto** | El usuario salta entre campos sin sentido | Configura el orden de tabulación (Edit > Edit Tab Order) |
| **Sin feedback al enviar** | El usuario no sabe si funcionó | Mensajes de confirmación, cambios en el botón |
---
Ejercicio Práctico del Módulo
🏋️ EJERCICIO 11: Formulario de Registro de Clientes Completo
>
Objetivo: Crear un formulario de registro profesional con múltiples secciones.
>
Pasos:
1. Crea un Dialog with Buttons Bottom de 550x650 píxeles
2. Cambia el
windowTitlea "Registro de Cliente"3. Cambia el fondo:
styleSheet: background-color: #1a1a2e;4. Aplica un Layout Vertical al Dialog completo
5. Agrega un Label de título: "Registro de Cliente" (fuente 22pt, Bold, blanco, centrado)
6. Agrega un Scroll Area para el contenido (por si el formulario es largo)
7. Dentro del Scroll Area, aplica un Layout Vertical al widget interno
8. Agrega un Group Box "Datos Personales" con Form Layout:
- Label "Nombre completo:*" + Line Edit (placeholder: "Juan Pérez García")
- Label "Email:*" + Line Edit (placeholder: "juan@email.com")
- Label "Teléfono:" + Line Edit (inputMask:
000-000-0000)- Label "Fecha de nacimiento:" + Date Edit
- Label "Género:" + 3 Radio Buttons (Masculino, Femenino, Prefiero no decir)
9. Agrega un Group Box "Dirección" con Form Layout:
- Label "Calle:" + Line Edit (placeholder: "Calle y número")
- Label "Colonia:" + Line Edit
- Label "Ciudad:" + Line Edit
- Label "Estado:" + Combo Box (agrega al menos 5 estados)
- Label "Código Postal:" + Line Edit (maxLength: 5)
- Label "País:" + Combo Box (México, España, Argentina, Colombia, Otro)
10. Agrega un Group Box "Preferencias":
- Check Box: "Deseo recibir el newsletter semanal"
- Check Box: "Acepto recibir promociones por email"
- Check Box: "Acepto los términos y condiciones"
- Label "Frecuencia de contacto preferida:" + Slider (min: 1, max: 10)
- Label al lado del slider mostrando el valor (conecta con signal/slot)
11. Agrega un Group Box "Notas adicionales":
- Plain Text Edit con placeholder "Información adicional sobre el cliente..."
- minimumHeight: 80
12. Configura el sizePolicy del Plain Text Edit vertical a
Expanding13. Aplica el tema de formularios con Style Sheets
14. Renombra TODOS los widgets con nombres descriptivos
15. Configura el orden de tabulación (Edit > Edit Tab Order)
16. Guarda como
registro_cliente.ui17. Presiona
Ctrl+Ry prueba el formulario completo
>
Resultado esperado: Un formulario profesional con 4 secciones, campos variados, validación visual, sliders interactivos y un diseño coherente con tema oscuro.
---
Recursos Adicionales
| Recurso | Descripción |
|---|---|
| --------- | ------------- |
| [UX Design for Forms](https://www.nngroup.com/articles/web-form-design/) | Mejores prácticas de Nielsen Norman Group |
| [Form Design Patterns](https://www.smashingmagazine.com/printed-books/form-design-patterns/) | Libro gratuito de Smashing Magazine |
| [Qt Input Validation](https://doc.qt.io/qt-6/qlineedit.html#inputMask-prop) | Documentación de validación de entrada |
---
Evaluación de Comprensión
- ¿Cuáles son los 6 principios fundamentales de un buen formulario?
- ¿Qué widget usarías para agrupar campos relacionados en un formulario?
- ¿Cómo marcas visualmente un campo como obligatorio?
- ¿Qué es un input mask y para qué sirve?
- ¿Cuál es la diferencia entre un formulario de registro y un wizard?
- ¿Qué widget es ideal para un campo de mensaje largo?
- ¿Cómo configuras el orden en que el usuario navega entre campos con Tab?
- ¿Qué placeholder pondrías en un campo de contraseña?
- ¿Por qué es importante usar un Scroll Area en formularios largos?
- ¿Qué botones debería tener un formulario de configuración vs. uno de registro?
---
Módulo anterior: ← [Módulo 10: Diálogos](09-dialogos.md)
Siguiente módulo: → [Módulo 12: Widgets Especializados](11-widgets-especializados.md)
Escribe tus respuestas y luego presiona el botón para comparar con las respuestas correctas.
Ejercicio 11: Formulario de Registro de Clientes
Módulo 11: Formularios Completos
---
Objetivo
Crear un formulario de registro de clientes profesional con múltiples secciones.
---
Instrucciones
- Crea un Dialog with Buttons Bottom de 550x650 píxeles
windowTitle: "Registro de Cliente"- Fondo:
styleSheet: background-color: #1a1a2e; - Aplica un Layout Vertical al Dialog completo
- Label título: "Registro de Cliente" (22pt, Bold, blanco, centrado)
- Scroll Area para el contenido
- Dentro del Scroll Area, aplica un Layout Vertical al widget interno
Group Box "Datos Personales" (Form Layout):
- Label "Nombre completo:*" + Line Edit (placeholder: "Juan Pérez García")
- Label "Email:*" + Line Edit (placeholder: "juan@email.com")
- Label "Teléfono:" + Line Edit (inputMask:
000-000-0000) - Label "Fecha de nacimiento:" + Date Edit
- Label "Género:" + 3 Radio Buttons (Masculino, Femenino, Prefiero no decir)
Group Box "Dirección" (Form Layout):
- Label "Calle:" + Line Edit (placeholder: "Calle y número")
- Label "Colonia:" + Line Edit
- Label "Ciudad:" + Line Edit
- Label "Estado:" + Combo Box (al menos 5 estados)
- Label "Código Postal:" + Line Edit (maxLength: 5)
- Label "País:" + Combo Box (México, España, Argentina, Colombia, Otro)
Group Box "Preferencias":
- Check Box: "Deseo recibir el newsletter semanal"
- Check Box: "Acepto recibir promociones por email"
- Check Box: "Acepto los términos y condiciones"
- Label "Frecuencia de contacto:" + Slider (min: 1, max: 10)
- Label al lado del slider mostrando el valor (conecta con signal/slot)
Group Box "Notas adicionales":
- Plain Text Edit con placeholder "Información adicional sobre el cliente..."
- minimumHeight: 80
- sizePolicy vertical:
Expanding
- Aplica el tema de formularios con Style Sheets
- Renombra TODOS los widgets
- Configura el orden de tabulación (Edit > Edit Tab Order)
- Guarda como
registro_cliente.ui - Presiona
Ctrl+Ry prueba el formulario completo
---
Resultado Esperado
Un formulario profesional con 4 secciones, campos variados, validación visual, slider interactivo y diseño coherente con tema oscuro.
---
Checklist
- [ ] Dialog with Buttons Bottom de 550x650
- [ ] Layout Vertical al Dialog
- [ ] Scroll Area para contenido largo
- [ ] Group Box "Datos Personales" con 5 campos
- [ ] Group Box "Dirección" con 6 campos
- [ ] Group Box "Preferencias" con 3 checks + slider
- [ ] Group Box "Notas adicionales" con Plain Text Edit
- [ ] Slider conectado a Label (signal/slot)
- [ ] Tema oscuro coherente
- [ ] Orden de tabulación configurado
- [ ] Todos los widgets renombrados