Skip to content
> 💻 🧠 Codice 1001 > 📚 Materiali di Apprendimento > Materiali didattici FreeCAD > Creazione di Addon per FreeCAD > Lezione 4. Interfaccia grafica (GUI): finestra di dialogo con campi di input

Lezione 4. Interfaccia grafica (GUI): finestra di dialogo con campi di input

📘 Corso di formazione: Creazione di addon per FreeCAD

Obiettivo della lezione: creare una finestra con campi per l’inserimento di lunghezza, larghezza e altezza, e al clic di un pulsante costruire una scatola con questi parametri.


🖼 Parte 1. Come funziona la GUI in FreeCAD?

FreeCAD utilizza PySide — un wrapper Python per la libreria Qt (la stessa usata in Blender, Maya e molti altri programmi).

Componenti principali:

  • QtGui.QDialog — finestra modale
  • QtGui.QLineEdit — campo di input testuale
  • QtGui.QPushButton — pulsante
  • QtGui.QFormLayout — layout comodo “etichetta + campo”

💡 Tutti gli elementi GUI vengono creati all’interno dello script Python, senza file esterni (anche se è possibile utilizzare .ui da Qt Designer — ma inizieremo con il semplice).


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

Estenderemo l’addon precedente, aggiungendo una finestra di dialogo.

Passaggio 1. Crea una cartella

.../Mod/BoxBuilderAddon/

Passaggio 2. File InitGui.py

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

FreeCADGui.addWorkbench(BoxBuilderWorkbench())

Passaggio 3. File box_builder_workbench.py

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

# === FUNZIONE DI CREAZIONE SCATOLA ===
def create_box(length, width, height, name="CustomBox"):
    doc = FreeCAD.ActiveDocument
    if not doc:
        doc = FreeCAD.newDocument("BoxBuilder")

    # Nome unico
    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


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

        # Campi di input
        self.length_input = QtGui.QLineEdit("30.0")
        self.width_input = QtGui.QLineEdit("20.0")
        self.height_input = QtGui.QLineEdit("10.0")

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

        # Connessione dei pulsanti
        self.create_button.clicked.connect(self.on_create)
        self.cancel_button.clicked.connect(self.reject)

        # Layout
        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()  # Chiudi la finestra

        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_()  # Chiamata modale

    def IsActive(self):
        return True


# === AMBIENTE DI LAVORO ===
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())

🔍 Analisi delle parti chiave

1. Finestra di dialogo (BoxBuilderDialog)

  • Eredita da QtGui.QDialog
  • Utilizza QFormLayout per un posizionamento ordinato dei campi
  • Il pulsante Create Box chiama on_create(), Cancel — chiude la finestra

2. Elaborazione dell’input

  • Convertiamo il testo in float
  • Verifichiamo che i valori siano positivi
  • In caso di errore — mostriamo un avviso tramite QMessageBox.warning

3. Creazione dell’oggetto

  • La funzione create_box() è separata — per un codice più pulito
  • Genera un nome unico per evitare conflitti

4. Avvio della finestra

  • dialog.exec_() — rende la finestra modale (non è possibile interagire con FreeCAD finché è aperta)

▶️ Passaggio 4. Verifica del funzionamento

  1. Salva i file
  2. Riavvia FreeCAD
  3. Seleziona l’ambiente di lavoro «Box Builder»
  4. Clicca sul pulsante «Box Builder»
  5. Nella finestra che appare, inserisci le dimensioni → clicca su Create Box

✅ Dovrebbe apparire una scatola con i tuoi parametri!

Prova a:

  • Inserire lettere → apparirà un errore
  • Inserire un numero negativo → errore
  • Inserire numeri decimali (ad esempio, 12.5) → funziona!

🧪 Esercizio pratico

  1. Aggiungi un quarto campo: «Name» — in modo che l’utente possa specificare il nome dell’oggetto.
  2. Fai in modo che, se il nome è vuoto, venga utilizzato un valore predefinito ("CustomBox").
  3. Aggiungi una casella di controllo «Center on origin» — se selezionata, la scatola dovrebbe essere centrata all’origine.

💡 Suggerimento per la centratura:
Dopo aver creato la scatola, modifica la sua proprietà Placement:

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

💡 Consigli per lavorare con la GUI

  • Avvolgi sempre l’input in try/except — l’utente può inserire qualsiasi cosa
  • Utilizza QDoubleValidator per consentire solo numeri (opzionale)
  • Per interfacce complesse è meglio usare Qt Designer e caricare file .ui, ma per compiti semplici — il codice è più facile

▶️ Cosa c’è dopo?

Nella Lezione 5 impareremo a:

  • Salvare le impostazioni tra gli avvii di FreeCAD
  • Fare in modo che l’ultimo valore delle dimensioni inserito venga memorizzato
  • Utilizzare il meccanismo integrato di FreeCAD: FreeCAD.ParamGet()

Questo renderà il tuo addon ancora più comodo!

Leave a Reply

Your email address will not be published. Required fields are marked *