Saltar al contenido
> 💻 🧠 Código 1001 > 📖 Guías > FreeCAD (software) > Cómo crear addons para FreeCAD > Lección 4. Interfaz gráfica de usuario (GUI): cuadro de diálogo con campos de entrada

Lección 4. Interfaz gráfica de usuario (GUI): cuadro de diálogo con campos de entrada

  • por

📘 Curso: Creación de complementos para FreeCAD

Objetivo de la lección: crear una ventana con campos para introducir la longitud, la anchura y la altura, y al pulsar un botón construir una caja con esos parámetros.


🖼 Parte 1. ¿Cómo funciona la GUI en FreeCAD?

FreeCAD utiliza PySide, un envoltorio de Python sobre la biblioteca Qt (la misma que se usa en Blender, Maya y muchos otros programas).

Componentes principales:

  • QtGui.QDialog — ventana modal
  • QtGui.QLineEdit — campo de entrada de texto
  • QtGui.QPushButton — botón
  • QtGui.QFormLayout — diseño cómodo de «etiqueta + campo»

💡 Todos los elementos de la GUI se crean dentro del script de Python, sin archivos externos (aunque se puede usar .ui de Qt Designer, pero empezaremos con algo sencillo).


🛠 Parte 2. Complemento: «Box Builder con GUI»

Ampliaremos el complemento anterior añadiendo un cuadro de diálogo.

Paso 1. Crea una carpeta

.../Mod/BoxBuilderAddon/

Paso 2. Archivo InitGui.py

# InitGui.py
import FreeCADGui
from BoxBuilderAddon.box_builder_workbench import BoxBuilderWorkbench

FreeCADGui.addWorkbench(BoxBuilderWorkbench())

Paso 3. Archivo box_builder_workbench.py

# box_builder_workbench.py
import FreeCAD, FreeCADGui
from PySide import QtGui, QtCore

# === FUNCIÓN DE CREACIÓN DE CAJA ===
def create_box(length, width, height, name="CustomBox"):
    doc = FreeCAD.ActiveDocument
    if not doc:
        doc = FreeCAD.newDocument("BoxBuilder")

    # Nombre único
    base_name = name
    index = 1
    obj_name = base_name
    while obj_name in [obj.Name for obj in doc.Objects]:
        obj_name = f"{base_name}_{index}"
        index += 1

    box = doc.addObject("Part::Box", obj_name)
    box.Length = length
    box.Width = width
    box.Height = height
    doc.recompute()
    return box


# === CUADRO DE DIÁLOGO ===
class BoxBuilderDialog(QtGui.QDialog):
    def __init__(self):
        super(BoxBuilderDialog, self).__init__()
        self.setWindowTitle("Box Builder")
        self.setWindowFlags(QtCore.Qt.WindowStaysOnTopHint)
        self.resize(300, 150)

        # Campos de entrada
        self.length_input = QtGui.QLineEdit("30.0")
        self.width_input = QtGui.QLineEdit("20.0")
        self.height_input = QtGui.QLineEdit("10.0")

        # Botones
        self.create_button = QtGui.QPushButton("Create Box")
        self.cancel_button = QtGui.QPushButton("Cancel")

        # Conexión de botones
        self.create_button.clicked.connect(self.on_create)
        self.cancel_button.clicked.connect(self.reject)

        # Diseño
        layout = QtGui.QFormLayout()
        layout.addRow("Length (mm):", self.length_input)
        layout.addRow("Width (mm):", self.width_input)
        layout.addRow("Height (mm):", self.height_input)

        button_layout = QtGui.QHBoxLayout()
        button_layout.addWidget(self.create_button)
        button_layout.addWidget(self.cancel_button)

        main_layout = QtGui.QVBoxLayout()
        main_layout.addLayout(layout)
        main_layout.addLayout(button_layout)
        self.setLayout(main_layout)

    def on_create(self):
        try:
            length = float(self.length_input.text())
            width = float(self.width_input.text())
            height = float(self.height_input.text())

            if length <= 0 or width <= 0 or height <= 0:
                raise ValueError("All dimensions must be positive")

            create_box(length, width, height)
            self.accept()  # Cerrar ventana

        except ValueError as e:
            QtGui.QMessageBox.warning(self, "Input Error", f"Invalid input:\n{str(e)}")


# === COMANDO ===
class BoxBuilderCommand:
    def GetResources(self):
        return {
            "MenuText": "Box Builder",
            "ToolTip": "Create a box with custom dimensions"
        }

    def Activated(self):
        dialog = BoxBuilderDialog()
        dialog.exec_()  # Llamada modal

    def IsActive(self):
        return True


# === ENTORNO DE TRABAJO ===
class BoxBuilderWorkbench(FreeCADGui.Workbench):
    MenuText = "Box Builder"
    ToolTip = "Create custom boxes with GUI"

    def Initialize(self):
        self.list = ["BoxBuilderCommand"]
        self.appendToolbar("Box Tools", self.list)
        self.appendMenu("Box Builder", self.list)

    def GetClassName(self):
        return "Gui::PythonWorkbench"


FreeCADGui.addCommand("BoxBuilderCommand", BoxBuilderCommand())

🔍 Desglose de las partes clave

1. Cuadro de diálogo (BoxBuilderDialog)

  • Hereda de QtGui.QDialog
  • Utiliza QFormLayout para una colocación ordenada de los campos
  • El botón Create Box llama a on_create(), Cancel — cierra la ventana

2. Procesamiento de la entrada

  • Convertimos el texto a float
  • Comprobamos que los valores sean positivos
  • En caso de error — mostramos una advertencia a través de QMessageBox.warning

3. Creación del objeto

  • La función create_box() se ha extraído por separado — para un código más limpio
  • Genera un nombre único para evitar conflictos

4. Lanzamiento de la ventana

  • dialog.exec_() — hace que la ventana sea modal (no se puede interactuar con FreeCAD mientras esté abierta)

▶️ Paso 4. Comprobación del funcionamiento

  1. Guarda los archivos
  2. Reinicia FreeCAD
  3. Selecciona el entorno de trabajo «Box Builder»
  4. Haz clic en el botón «Box Builder»
  5. En la ventana que aparece, introduce las dimensiones → haz clic en Create Box

✅ ¡Debería aparecer una caja con tus parámetros!

Prueba a:

  • Introducir letras → aparecerá un error
  • Introducir un número negativo → error
  • Introducir números decimales (por ejemplo, 12.5) → ¡funciona!

🧪 Tarea práctica

  1. Añade un cuarto campo: «Name» — para que el usuario pueda establecer el nombre del objeto.
  2. Haz que si el nombre está vacío, se utilice el valor predeterminado ("CustomBox").
  3. Añade una casilla de verificación «Center on origin» — si está activada, la caja debe estar centrada en el origen.

💡 Sugerencia para centrar:
Después de crear la caja, cambia su propiedad Placement:

from FreeCAD import Vector
box.Placement.Base = Vector(-length/2, -width/2, -height/2)

💡 Consejos para trabajar con la GUI

  • Envuelve siempre la entrada en try/except — el usuario puede introducir cualquier cosa
  • Utiliza QDoubleValidator para permitir solo números (opcional)
  • Para interfaces complejas, es mejor usar Qt Designer y cargar archivos .ui, pero para tareas sencillas — el código es más fácil

▶️ ¿Qué sigue?

En la Lección 5 aprenderemos a:

  • Guardar configuraciones entre inicios de FreeCAD
  • Hacer que el último valor de las dimensiones introducidas se recuerde
  • Utilizar el mecanismo integrado de FreeCAD: FreeCAD.ParamGet()

¡Esto hará que tu complemento sea aún más cómodo!

Deja una respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *