Manual:Creating interface tools/it

Negli ultimi due capitoli, abbiamo visto come creare della geometria Parte e creare oggetti parametrici. Manca un ultimo pezzo per avere il pieno controllo su FreeCAD: creare strumenti che interagiscono con l'utente.

In molte situazioni, non è molto amichevole costruire un oggetto con valori zero, come abbiamo fatto con il rettangolo nel capitolo precedente, e poi chiedere all'utente di compilare i valori di altezza e larghezza nel pannello delle Proprietà. Questo va bene per un numero molto limitato di oggetti, ma diventa veramente noioso se si devono fare parecchi rettangoli. Sarebbe meglio poter assegnare l'altezza e la larghezza già durante la creazione del rettangolo.

Python offre uno strumento base che consente all'utente di inserire il testo dallo schermo:

text = raw_input("Height of the rectangle?") print("The entered height is ",text)

Però, questo richiede una console Python in esecuzione, e quando si esegue il codice da una macro, non siamo sempre sicuri che la console Python sia attiva sulla macchina dell'utente.

La Graphical User Interface, o GUI, cioè, tutta la parte di FreeCAD che viene visualizzata sullo schermo (menu, barre degli strumenti, vista 3D, ecc), è tutta lì per questo scopo: interagire con l'utente. L'interfaccia di FreeCAD è costruita con Qt, un kit di strumenti GUI open-source molto comune che offre una vasta gamma di strumenti quali finestre di dialogo, pulsanti, etichette, caselle di testo o menu a discesa (tutti questi sono genericamente chiamati "widget").

Gli strumenti Qt sono molto facili da usare da Python, grazie ad un modulo Python chiamato Pyside (ci sono anche molti altri moduli Python per comunicare con Qt da Python). Questo modulo permette di creare e interagire con i widget, leggere ciò che l'utente ha fatto con essi (leggere quello che è stato inserito nelle caselle di testo) o fare qualcosa quando, ad esempio, viene premuto un pulsante.

Qt fornisce anche un altro strumento interessante chiamato Qt Designer, che attualmente è incorporato all'interno di un'applicazione più grande chiamata Qt Creator. Esso consente di progettare finestre di dialogo e pannelli dell'interfaccia grafica, invece di doverli codificare manualmente. In questo capitolo, useremo Qt Creator per la progettazione di un pannello widget che useremo nel pannello Azioni di FreeCAD. Quindi è necessario scaricare e installare Qt Creator dalla sua official page se siete su Windows o Mac (su Linux di solito è disponibile tramite il gestore del software).

Nel seguente esercizio, per prima cosa con Qt Creator creeremo un pannello che richieda i valori di lunghezza, larghezza e altezza, poi creeremo su di esso una classe Python che legga nel pannello i valori inseriti dall'utente, e crei un scatola con le dimensioni indicate. Questa classe Python sarà poi utilizzata da FreeCAD per visualizzare e controllare il pannello delle azioni:



Cominciamo creando il widget. Avviare Qt Creator, quindi nel menu File -> New File or Project -> Files and Classes -> Qt -> Qt Designer Form -> Dialog without buttons. Cliccare Next, dare un nome per salvare il file, fare clic su Next, lasciare tutti i campi del progetto al loro valore di default (" "), e poi su Create. Il sistema Azioni di FreeCAD aggiungerà automaticamente i pulsanti OK e Annulla, è per questo che abbiamo scelto un dialogo senza pulsanti.




 * Find the Label in the list in the left panel, and drag it onto the canvas of our widget. Double-click the recent placed Label, and change its text to Length.
 * Right-click the widget canvas, and choose Lay out-> Lay out in a Grid. This will turn our widget into a grid with currently only one cell, occupied by ourfirst label. We can now add the next items at the left, right, top or bottom of our first label, and the grid will expand automatically.
 * Add two more labels below the first one, and change their text to Width and Height:




 * Now place 3 Double Spin Box widgets next to our Length, Width and Height labels. For each of them, in the lower left panel, which shows all the available settings for the selected widget, locate Suffix and set their suffix to mm. FreeCAD has a more advanced widget, that can handle different units, but that is not available in Qt Creator by default (but can be compiled), so for now we will use a standard Double Spin Box, and we add the "mm" suffix to make sure the user knows in which units they work:




 * Now our widget is done, we just need to make sure of one last thing. Since FreeCAD will need to access that widget and read the Length, Width and Height values, we need to give proper names to those widgets, so we can easily retrive them from within FreeCAD. Click each of the Double Spin Boxes, and in the upper right window, double-click their Object Name, and change them to something easy to remember, for example: BoxLength, BoxWidth and BoxHeight:




 * Save the file, you can now close Qt Creator, the rest will be done in Python.
 * Open FreeCAD and create a new macro from menu Macro -> Macros -> Create
 * Paste the following code. Make sure you change the file path to match where you saved the .ui file created in QtCreator:

import FreeCAD,FreeCADGui,Part path_to_ui = "C:\Users\yorik\Documents\dialog.ui" class BoxTaskPanel: def __init__(self): # this will create a Qt widget from our ui file self.form = FreeCADGui.PySideUic.loadUi(path_to_ui) def accept(self): length = self.form.BoxLength.value width = self.form.BoxWidth.value height = self.form.BoxHeight.value if (length == 0) or (width == 0) or (height == 0): print("Error! None of the values can be 0!") # we bail out without doing anything return box = Part.makeBox(length,width,height) Part.show(box) FreeCADGui.Control.closeDialog panel = BoxTaskPanel FreeCADGui.Control.showDialog(panel)
 * 1) CHANGE THE LINE BELOW

In the code above, we used a convenience function (PySideUic.loadUi) from the FreeCADGui module. That function loads a .ui file, creates a Qt Widget from it, and maps names, so we can easily access the subwidget by their names (ex: self.form.BoxLength).

The "accept" function is also a convenience offered by Qt. When there is a "OK" button in a dialog (which is the case by default when using the FreeCAD Tasks panel), any funcion named "accept" will automatically be executed when the "OK" button is pressed. Similarily, you can also add a "reject" function which gets executed when the "Cancel" button is pressed. In our case, we ommitted that function, so pressing "Cancel" will do the default behaviour (do nothing and close the dialog).

If we implement any of the accept or reject functions, their default behaviour (do nothing and close) will not occur anymore. So we need to close the Task panel ourselves. This is done with:

FreeCADGui.Control.closeDialog

Once we have our BoxTaskPanel that has 1) a widget called "self.form" and 2) if needed, accept and reject functions, we can open the task panel with it, which is done with these two last lines:

panel = BoxTaskPanel FreeCADGui.Control.showDialog(panel)

Note that the widget created by PySideUic.loadUi is not specific to FreeCAD, it is a standard Qt widget which can be used with other Qt tools. For example, we could have shown a separate dialog box with it. Try this in the Python Console of FreeCAD (using the correct path to your .ui file of course):

from PySide import QtGui w = FreeCADGui.PySideUic.loadUi("C:\Users\yorik\Documents\dialog.ui") w.show

Of course we didn't add any "OK" or "Cancel" button to our dialog, since it was made to be used from the FreeCAD Task panel, which already provides such buttons. So there is no way to close the dialog (other than pressing its Window Close button). But the function show creates a non-modal dialog, which means it doesn't block the rest of the interface. So, while our dialog is still open, we can read the values of the fields:

w.BoxHeight.value

This is very useful for testing.

Finally, don't forget there is much more documentation about using Qt widgets on the FreeCAD Wiki, in the Python Scripting section, which contains a dialog creation tutorial, a special 3-part PySide tutorial that covers the subject extensively.

Read more


 * Qt Creator
 * Installing Qt Creator
 * Python scripting documentation
 * Dialog creation tutorial
 * PySide tutorials
 * PySide documentation