Módulo 5: Layouts — El Arte de la Composición
El concepto más importante para crear interfaces profesionales y responsivas
El concepto más importante para crear interfaces profesionales y responsivas
---
Objetivos de Aprendizaje
Al finalizar este módulo serás capaz de:
- Comprender qué son los layouts y por qué son absolutamente esenciales
- Aplicar Vertical Layout, Horizontal Layout, Grid Layout y Form Layout
- Combinar layouts anidados para crear interfaces complejas
- Usar Spacers para controlar el espacio flexible
- Configurar Size Policy para controlar el comportamiento de los widgets al redimensionar
- Crear interfaces que se adaptan a cualquier tamaño de ventana
- Identificar y corregir problemas comunes de layout
---
5.1 ¿Qué son los Layouts y por qué son CRUCIALES?
Los Layouts son reglas invisibles que controlan cómo se posicionan y redimensionan los widgets dentro de un contenedor. Son el concepto más importante que aprenderás en este curso.
🎨 ANALOGÍA DEL DISEÑO
>
Los Layouts son como las guías y cuadrículas (grids) que usas en InDesign o Figma. En lugar de colocar cada elemento pixel por pixel (posición absoluta), defines reglas de composición:
>
- "Este texto va arriba"
- "Estos botones van uno al lado del otro"
- "Esta imagen ocupa todo el espacio disponible"
>
Cuando el usuario redimensiona la ventana, todo se ajusta automáticamente.
El problema de NO usar layouts
Sin layouts, colocas widgets en posiciones fijas (posición absoluta). Esto causa problemas:
| Problema | Descripción |
|---|---|
| ---------- | ------------- |
| **Se rompe al redimensionar** | Si el usuario cambia el tamaño de la ventana, los widgets se quedan en su posición original |
| **Diferentes resoluciones** | Tu diseño se ve perfecto en TU pantalla pero se ve mal en otras resoluciones |
| **Diferentes idiomas** | Textos más largos en alemán que en español pueden salirse del espacio asignado |
| **Diferentes fuentes** | Si el usuario cambia el tamaño de fuente del sistema, todo se desajusta |
⚠️ IMPORTANTE
>
Sin Layouts, tu interfaz se rompe cuando el usuario cambia el tamaño de la ventana, usa una resolución diferente, o cambia el idioma. Siempre usa Layouts.
---
5.2 Vertical Layout (QVBoxLayout)
Apila los widgets uno encima del otro, de arriba hacia abajo.
Cómo aplicarlo
- Selecciona los widgets que quieres apilar (mantén presionado
Ctrly haz clic en cada uno) - Haz clic en el botón Lay Out Vertically en la toolbar (o presiona
Ctrl+L) - Los widgets se apilan automáticamente con espaciado uniforme
Visualización
┌─────────────────────────┐
│ Widget 1 (arriba) │
├─────────────────────────┤
│ Widget 2 (medio) │
├─────────────────────────┤
│ Widget 3 (abajo) │
└─────────────────────────┘
Propiedades del Layout Vertical
| Propiedad | Descripción | Valor por defecto |
|---|---|---|
| ----------- | ------------- | ------------------- |
| **layoutSpacing** | Espacio entre widgets (en píxeles) | `6` |
| **layoutLeftMargin** | Margen izquierdo | `9` |
| **layoutRightMargin** | Margen derecho | `9` |
| **layoutTopMargin** | Margen superior | `9` |
| **layoutBottomMargin** | Margen inferior | `9` |
| **layoutStretch** | Cómo se reparte el espacio extra | `0,0,0` (igual para todos) |
Cómo ajustar el espaciado
- Selecciona el contenedor que tiene el layout (no un widget individual)
- En el Property Editor, busca las propiedades que empiezan con
layout... - Cambia
layoutSpacingpara más o menos espacio entre widgets - Cambia los márgenes para más o menos espacio en los bordes
---
5.3 Horizontal Layout (QHBoxLayout)
Coloca los widgets uno al lado del otro, de izquierda a derecha.
Cómo aplicarlo
- Selecciona los widgets
- Haz clic en Lay Out Horizontally (o presiona
Ctrl+H)
Visualización
┌─────────────────────────────────────────────────┐
│ [Botón 1] [Botón 2] [Botón 3] │
└─────────────────────────────────────────────────┘
Cuándo usar Horizontal Layout
- Barras de botones (Cancelar, Aceptar)
- Label + campo de entrada en la misma línea
- Iconos de toolbar
- Elementos de navegación horizontal
🎨 ANALOGÍA DEL DISEÑO
>
Un Vertical Layout es como una columna en un periódico. Un Horizontal Layout es como los elementos de una barra de navegación.
---
5.4 Grid Layout (QGridLayout)
Organiza los widgets en una cuadrícula de filas y columnas. Es como una tabla de Excel donde cada celda puede contener un widget.
Cómo aplicarlo
- Selecciona los widgets
- Haz clic en Lay Out in a Grid (o presiona
Ctrl+J) - Los widgets se organizan en filas y columnas automáticamente según su posición actual
Visualización
┌──────────────────┬──────────────────┐
│ Fila 1, Col 1 │ Fila 1, Col 2 │
├──────────────────┼──────────────────┤
│ Fila 2, Col 1 │ Fila 2, Col 2 │
└──────────────────┴──────────────────┘
Cuándo usar Grid Layout
- Formularios con labels a la izquierda y campos a la derecha
- Galerías de imágenes en cuadrícula
- Calculadoras (botones en filas y columnas)
- Cualquier disposición que necesite alineación en dos dimensiones
💡 CONSEJO: El Grid Layout es perfecto para formularios donde tienes labels a la izquierda y campos de entrada a la derecha. Pero para ese caso específico, el Form Layout (siguiente sección) es aún mejor.
---
5.5 Form Layout (QFormLayout)
Especializado para formularios con etiquetas y campos. Crea automáticamente pares label-campo alineados profesionalmente.
Cómo aplicarlo
- Selecciona pares de widgets (label + campo de entrada)
- Haz clic en Lay Out in a Form Layout
- Las etiquetas se alinean automáticamente a la derecha y los campos a la izquierda
Visualización
┌─────────────────────────────────────────┐
│ Nombre: [____________] │
│ Email: [____________] │
│ Edad: [____] │
│ Ciudad: [____________] │
└─────────────────────────────────────────┘
Propiedades del Form Layout
| Propiedad | Descripción | Valores |
|---|---|---|
| ----------- | ------------- | --------- |
| **labelAlignment** | Alineación de las etiquetas | `AlignLeft`, `AlignRight` |
| **formAlignment** | Alineación del formulario completo | `AlignTop`, `AlignBottom`, `AlignHCenter`, `AlignJustify` |
| **fieldGrowthPolicy** | Cómo crecen los campos | `AllNonFixedFieldsGrow`, `FieldsStayAtSizeHint`, `ExpandingFieldsGrow` |
| **rowWrapPolicy** | Cuándo envolver filas | `DontWrapRows`, `WrapLongRows`, `WrapAllRows` |
🎨 ANALOGÍA DEL DISEÑO
>
El Form Layout es como usar las columnas guía de InDesign para alinear texto e imágenes perfectamente. Tú no calculas las posiciones: el layout lo hace por ti.
---
5.6 Layouts Anidados — La Clave del Diseño Profesional
El verdadero poder de los layouts viene cuando los combinas. Un layout puede contener otros layouts, creando estructuras complejas.
Ejemplo típico de una ventana profesional
┌─────────────────────────────────────────────────────┐
│ Layout Vertical (ocupa toda la ventana) │
│ ┌───────────────────────────────────────────────┐ │
│ │ Label: "Registro de Usuario" (título) │ │
│ ├───────────────────────────────────────────────┤ │
│ │ Layout Horizontal │ │
│ │ ┌─────────────────┐ ┌────────────────────┐ │ │
│ │ │ Layout Vertical │ │ Layout Vertical │ │ │
│ │ │ (formulario) │ │ (botones de acción)│ │ │
│ │ │ - Label + Input │ │ - Botón 1 │ │ │
│ │ │ - Label + Input │ │ - Botón 2 │ │ │
│ │ │ - Label + Input │ │ - Botón 3 │ │ │
│ │ └─────────────────┘ └────────────────────┘ │ │
│ ├───────────────────────────────────────────────┤ │
│ │ Layout Horizontal (botones inferiores) │ │
│ │ [Spacer] [Cancelar] [Registrarse] │ │
│ └───────────────────────────────────────────────┘ │
└─────────────────────────────────────────────────────┘
Cómo crear layouts anidados
- Primero crea los layouts internos (los más pequeños)
- Luego crea los layouts externos que los contienen
- Los layouts se pueden arrastrar dentro de otros layouts
Paso a paso: Formulario con layouts anidados
Paso 1: Crea el Layout Vertical del formulario
┌─────────────────────┐
│ Label: "Nombre:" │
│ Line Edit │
│ Label: "Email:" │
│ Line Edit │
└─────────────────────┘
Paso 2: Crea el Layout Horizontal de botones
┌─────────────────────────────────┐
│ [Spacer] [Cancelar] [OK] │
└─────────────────────────────────┘
Paso 3: Combina ambos en un Layout Vertical principal
┌─────────────────────────────────┐
│ [Layout del formulario] │
│ │
│ [Layout de botones] │
└─────────────────────────────────┘
---
5.7 Spacers — El Espacio en Blanco
Horizontal Spacer y Vertical Spacer son widgets invisibles que empujan otros widgets. Son como el "espacio en blanco" en diseño gráfico: dan respiro y organización visual.
Cómo usar Spacers
- Arrastra un Spacer desde el Widget Box (categoría "Spacers")
- Colócalo dentro de un layout
- El Spacer ocupa todo el espacio disponible, empujando los demás widgets
Ejemplo: Botones alineados a la derecha
Sin Spacer:
┌─────────────────────────────────┐
│ [Cancelar] [Aceptar] │
└─────────────────────────────────┘
Con Horizontal Spacer:
┌─────────────────────────────────┐
│ [Cancelar][Aceptar]│
│ ←─── Spacer ocupa todo esto ───→│
└─────────────────────────────────┘
Ejemplo: Widget centrado
┌─────────────────────────────────┐
│ [Spacer] [Widget] [Spacer] │
│ ←espacio→ ←fijo→ ←espacio→ │
└─────────────────────────────────┘
🎨 ANALOGÍA DEL DISEÑO
>
Los Spacers son como el margen automático en un diseño. En lugar de calcular manualmente cuánto espacio dejar, el Spacer "absorbe" todo el espacio sobrante y empuja los elementos hacia donde los necesitas.
---
5.8 Size Policy — Cómo los Widgets Deciden su Tamaño
Cada widget tiene una propiedad sizePolicy que controla cómo se comporta cuando el layout le da más o menos espacio del que pidió.
Políticas de Tamaño
| Size Policy | Comportamiento Horizontal | Comportamiento Vertical | Cuándo usar |
|---|---|---|---|
| ------------- | -------------------------- | ------------------------ | ------------- |
| **Fixed** | No crece ni encoge | No crece ni encoge | Botones, iconos, logos |
| **Minimum** | Puede crecer si hay espacio | Puede crecer si hay espacio | Widgets que deben ser al menos de cierto tamaño |
| **Maximum** | Puede encoger hasta su mínimo | Puede encoger hasta su mínimo | Widgets que no deben ser muy grandes |
| **Preferred** | Tamaño ideal, pero puede ajustarse | Tamaño ideal, pero puede ajustarse | Labels, textos |
| **Expanding** | Quiere todo el espacio posible | Quiere todo el espacio posible | Áreas de texto, listas, tablas |
| **MinimumExpanding** | Crece para llenar espacio | Crece para llenar espacio | Similar a Expanding pero con mínimo garantizado |
| **Ignored** | Ignora su sizeHint | Ignora su sizeHint | Raro, para casos especiales |
Cómo cambiar el Size Policy
- Selecciona el widget
- En el Property Editor, busca sizePolicy
- Expande la propiedad para ver
horizontalPolicyyverticalPolicy - Cambia cada una independientemente
🎨 ANALOGÍA DEL DISEÑO
>
Piensa en Size Policy como la flexibilidad de un elemento en un diseño responsive:
>
- Un botón tiene size policy "Fixed" porque su tamaño no debe cambiar
- Un área de texto tiene "Expanding" porque debe ocupar todo el espacio disponible
- Es como definir si un elemento es "fluido" o "rígido" en tu maqueta
Ejemplo práctico de Size Policy
Ventana con un Text Edit que debe ocupar todo el espacio:
┌───────────────────────────────┐
│ Label: "Comentarios:" │ ← sizePolicy: Preferred (tamaño natural)
├───────────────────────────────┤
│ │
│ │ ← Text Edit con sizePolicy: Expanding
│ (ocupa todo el espacio) │ (crece para llenar el espacio disponible)
│ │
│ │
├───────────────────────────────┤
│ [Enviar] [Cancelar] │ ← sizePolicy: Fixed (tamaño fijo)
└───────────────────────────────┘
---
5.9 layoutStretch — Controlar la Distribución del Espacio
La propiedad layoutStretch controla cómo se reparte el espacio extra entre los widgets de un layout.
Cómo funciona
Los valores son una lista de números separados por comas. Cada número representa la proporción de espacio que recibe ese widget.
| Stretch values | Resultado |
|---|---|
| ---------------- | ----------- |
| `0,0,0` | Todos reciben el mismo espacio extra (por defecto) |
| `1,2,1` | El widget del medio recibe el doble de espacio |
| `0,1,0` | Solo el widget del medio crece, los otros mantienen su tamaño |
| `3,1` | El primer widget recibe 3 veces más espacio que el segundo |
Cómo ajustar layoutStretch
- Selecciona el contenedor que tiene el layout
- En el Property Editor, busca layoutStretch
- Ingresa los valores separados por comas
Ejemplo: Sidebar + Contenido principal
Layout Horizontal con stretch "1,4":
┌──────┬────────────────────────────┐
│ │ │
│ 1 │ 4 │
│ │ │
│Sidebar│ Contenido principal │
│ │ │
└──────┴────────────────────────────┘
El contenido principal recibe 4 veces más espacio que el sidebar.
---
5.10 Romper un Layout
A veces necesitas deshacer un layout para reorganizar los widgets.
Cómo romper un layout
- Selecciona el contenedor que tiene el layout
- Haz clic en el botón Break Layout en la toolbar
- Los widgets quedan en sus posiciones actuales pero sin layout
💡 CONSEJO: Después de romper un layout, los widgets quedan en posiciones absolutas. No olvides aplicar un nuevo layout después de reorganizar.
---
5.11 Ajustar al Tamaño Ideal
El botón Adjust Size (Ctrl+0) redimensiona los widgets a su tamaño ideal (sizeHint).
Cuándo usarlo
- Después de cambiar el texto de un widget y necesita más espacio
- Para verificar que todos los widgets tienen el tamaño correcto
- Antes de aplicar un layout, para asegurarte de que los widgets no están demasiado pequeños
---
5.12 Errores Comunes con Layouts
| Error | Problema | Solución |
|---|---|---|
| ------- | ---------- | ---------- |
| **Widgets sin layout** | Se desalinean al redimensionar | Aplica siempre un layout al contenedor padre |
| **Layout applied to wrong widget** | El layout no afecta a los widgets correctos | Selecciona el contenedor padre antes de aplicar el layout |
| **Spacers olvidados** | Los botones quedan a la izquierda en lugar de a la derecha | Agrega un Horizontal Spacer antes de los botones |
| **Size Policy incorrecto** | Un widget crece demasiado o no crece lo suficiente | Ajusta el sizePolicy de cada widget |
| **layoutStretch no configurado** | Todos los widgets crecen igual | Configura layoutStretch para dar más espacio a los widgets que lo necesitan |
| **No probar al redimensionar** | No sabes si funciona en otros tamaños | Presiona `Ctrl+R` y redimensiona la ventana de vista previa |
⚠️ IMPORTANTE
>
El error más común de los principiantes es colocar widgets "a ojo" sin layouts. Tu diseño se verá perfecto en TU pantalla, pero se romperá en cualquier otra resolución. Layouts desde el inicio, siempre.
---
5.13 Checklist de Layouts
Antes de considerar un diseño como terminado, verifica:
- [ ] El widget/ventana principal tiene un layout aplicado
- [ ] Todos los contenedores internos tienen layouts
- [ ] Los Spacers están donde se necesita espacio flexible
- [ ] Los widgets que deben crecer tienen sizePolicy
Expanding - [ ] Los widgets que deben mantener su tamaño tienen sizePolicy
Fixed - [ ] El layoutStretch está configurado para distribuir el espacio correctamente
- [ ] La vista previa se ve bien al redimensionar la ventana
- [ ] Los márgenes y espaciado son consistentes
---
Ejercicio Práctico del Módulo
🏋️ EJERCICIO 5: Formulario de Registro Profesional y Responsivo
>
Objetivo: Crear un formulario de registro que se adapte perfectamente a cualquier tamaño de ventana.
>
Pasos:
1. Crea un Dialog sin botones
2. Cambia el
windowTitlea "Registro de Usuario"3. Cambia el fondo:
styleSheet: background-color: #1a1a2e;4. Aplica un Layout Vertical al Dialog completo:
- Haz clic derecho en el Dialog (en el Object Inspector) > Lay Out > Lay Out Vertically
5. Agrega un Label de título: "Registro de Usuario" (fuente 20pt, blanco, centrado)
6. Agrega un Frame como contenedor del formulario:
-
styleSheet: background-color: #2d2d3d; border-radius: 12px;- Aplica un Layout Vertical al Frame
7. Dentro del Frame, agrega un Form Layout con:
- Label "Nombre:" + Line Edit (placeholder: "Tu nombre completo")
- Label "Email:" + Line Edit (placeholder: "tu@email.com")
- Label "País:" + Combo Box (agrega al menos 5 países)
- Label "Bio:" + Plain Text Edit (placeholder: "Cuéntanos sobre ti...")
8. Debajo del Frame, agrega un Horizontal Layout con:
- Horizontal Spacer (empuja los botones a la derecha)
- Push Button "Cancelar"
- Push Button "Registrarse" (estilizado con fondo verde)
9. Configura el sizePolicy del Plain Text Edit vertical a
Expanding10. Configura layoutStretch del Layout Vertical principal a
0,1,011. Renombra todos los widgets
12. Guarda como
formulario_registro.ui13. Presiona
Ctrl+Ry redimensiona la ventana para verificar que todo se adapta
>
Resultado esperado: Un formulario elegante que se redimensiona correctamente, con el área de bio creciendo y los botones siempre alineados a la derecha.
---
Recursos Adicionales
| Recurso | Descripción |
|---|---|
| --------- | ------------- |
| [Qt Layout Management](https://doc.qt.io/qt-6/layout.html) | Documentación oficial sobre layouts |
| [QVBoxLayout](https://doc.qt.io/qt-6/qvboxlayout.html) | Documentación de Vertical Layout |
| [QHBoxLayout](https://doc.qt.io/qt-6/qhboxlayout.html) | Documentación de Horizontal Layout |
| [QGridLayout](https://doc.qt.io/qt-6/qgridlayout.html) | Documentación de Grid Layout |
| [QFormLayout](https://doc.qt.io/qt-6/qformlayout.html) | Documentación de Form Layout |
---
Evaluación de Comprensión
- ¿Por qué es crucial usar layouts en lugar de posiciones fijas?
- ¿Cuál es la diferencia entre Vertical Layout y Horizontal Layout?
- ¿Cuándo usarías un Grid Layout y cuándo un Form Layout?
- ¿Qué hace un Horizontal Spacer?
- ¿Qué sizePolicy usarías para un Text Edit que debe ocupar todo el espacio disponible?
- ¿Qué significa layoutStretch "1,3,1"?
- ¿Cómo aplicas un layout a un contenedor?
- ¿Qué atajo de teclado aplica un Layout Vertical?
- ¿Qué propiedad controla el espacio entre widgets en un layout?
- ¿Cómo verificas que tu diseño funciona correctamente en diferentes tamaños?
---
Módulo anterior: ← [Módulo 4: Contenedores](03-contenedores.md)
Siguiente módulo: → [Módulo 6: Signals y Slots](05-signals-slots.md)
Escribe tus respuestas y luego presiona el botón para comparar con las respuestas correctas.
Ejercicio 5: Formulario de Registro Responsivo
Módulo 5: Layouts
---
Objetivo
Crear un formulario de registro profesional y completamente responsivo.
---
Instrucciones
- Crea un Dialog sin botones
windowTitle: "Registro de Usuario"- Fondo:
styleSheet: background-color: #1a1a2e; - Aplica un Layout Vertical al Dialog completo:
- Clic derecho en el Dialog (Object Inspector) > Lay Out > Lay Out Vertically
- Label de título: "Registro de Usuario" (20pt, blanco, centrado)
- Frame como contenedor del formulario:
styleSheet: background-color: #2d2d3d; border-radius: 12px;- Aplica un Layout Vertical al Frame
- Dentro del Frame, Form Layout con:
- Label "Nombre:" + Line Edit (placeholder: "Tu nombre completo")
- Label "Email:" + Line Edit (placeholder: "tu@email.com")
- Label "País:" + Combo Box (al menos 5 países)
- Label "Bio:" + Plain Text Edit (placeholder: "Cuéntanos sobre ti...")
- Debajo del Frame, Horizontal Layout con:
- Horizontal Spacer (empuja botones a la derecha)
- Push Button "Cancelar"
- Push Button "Registrarse" (estilizado en verde)
- Configura el sizePolicy del Plain Text Edit vertical a
Expanding - Configura
layoutStretchdel Layout Vertical principal a0,1,0 - Renombra todos los widgets
- Guarda como
formulario_registro.ui - Presiona
Ctrl+Ry redimensiona la ventana para verificar que todo se adapta
---
Resultado Esperado
Un formulario elegante que se redimensiona correctamente, con el área de bio creciendo y los botones siempre alineados a la derecha.
---
Checklist
- [ ] Layout Vertical aplicado al Dialog
- [ ] Label de título centrado
- [ ] Frame con estilo de tarjeta
- [ ] Form Layout con 4 campos
- [ ] Horizontal Layout con Spacer + 2 botones
- [ ] Plain Text Edit con sizePolicy Expanding
- [ ] layoutStretch configurado a 0,1,0
- [ ] Se adapta correctamente al redimensionar