Workbench creation/it: Difference between revisions

From FreeCAD Documentation
(Updating to match new version of source page)
No edit summary
 
(66 intermediate revisions by 3 users not shown)
Line 1: Line 1:
<languages/>
<languages/>


{{Docnav
{{Docnav/it
|[[Localisation|Localisation]]
|[[Localisation/it|Localizzazione]]
|[[Extra_python_modules|Extra Python modules]]
|[[Extra_python_modules/it|Moduli Python aggiuntivi]]
}}
}}


{{TOCright}}
{{TOCright}}


== Introduction ==
<span id="Introduction"></span>
== Introduzione ==


Questa pagina da indicazioni su come aggiungere un nuovo ambiente di lavoro all'interfaccia di FreeCAD. Gli [[Workbenches/it|Ambienti di Lavoro]] sono contenitori per i comandi di FreeCAD. Possono essere codificati in Python, in C++ o in un mix di entrambi, il che ha il vantaggio di unire la velocità del C++ alla flessibilità di Python. In tutti i casi, tuttavia, l'ambiente verrà avviato da un set di due file Python. Possono essere ambienti di lavoro "interni", inclusi nella distribuzione di FreeCAD, o ambienti di lavoro "esterni", distribuiti tramite l'[[Std_AddonMgr/it|Addon Manager]] o installati manualmente scaricandoli da qualche repository online. Gli Ambienti di lavoro interni possono essere codificati in C++, Python o una combinazione dei due, mentre i workbench esterni devono essere solo in Python.
<div class="mw-translate-fuzzy">
Questa pagina spiega come aggiungere un nuovo ambiente di lavoro (Workbench) all'interfaccia di FreeCAD. Gli [[Workbenches/it|Workbenches]] sono dei contenitori per i comandi di FreeCAD. Essi possono essere codificati in python, in C++, o in una combinazione di entrambi, con il vantaggio di unire la velocità di C++ alla flessibilità di python. In tutti i casi, il vostro ambiente di lavoro sarà comunque lanciato da un insieme di due file python.
</div>


<span id="The_workbench_structure"></span>
== La struttura del workbench ==
== La struttura dell'Ambiente di lavoro ==


È necessaria una cartella, con qualsiasi nome si voglia, collocata nella directory Mod dell'utente, con un file {{incode|Init.py}} e, facoltativamente, un file {{incode|InitGui.py}}. Il file Init viene eseguito all'avvio di FreeCAD e il file {{incode|InitGui.py}} viene eseguito immediatamente dopo, ma solo quando FreeCAD si avvia in modalità GUI. Questo è tutto ciò che serve a FreeCAD per trovare l'ambiente di lavoro all'avvio e aggiungerlo alla propria interfaccia.
<div class="mw-translate-fuzzy">
Fondamentalmente è semplice: serve una cartella, con un nome a piacere, inserita nella directory Mod, contenente un file ''Init.py'' e, facoltativamente, un file ''InitGui.py''. Il file Init viene sempre eseguito all'avvio FreeCAD, e il file InitGui.py viene eseguito immediatamente dopo, ma solo quando FreeCAD si avvia in modalità GUI, non in modalità console. Questo è tutto ciò che serve a FreeCAD per trovare il vostro ambiente di lavoro in fase di avvio e aggiungerlo alla sua interfaccia.
</div>


The user Mod directory is a sub-directory of the user application data directory (you can find the latter by typing {{incode|App.getUserAppDataDir()}} in the [[Python_console|Python console]]):
La cartella utente Mod è una sottocartella della cartella dei dati dell'applicazione utente (si può trovare quest'ultima digitando {{incode|App.getUserAppDataDir()}} nella [[Python_console/it|console Python]]):
* On Linux it is usually {{FileName|/home/<username>/.FreeCAD/Mod/}}.
* Per Linux è solitamente {{FileName|/home/<username>/.local/share/FreeCAD/Mod/}} ({{VersionPlus/it|0.20}}) o {{FileName|/home/<username>/.FreeCAD/Mod/}} ({{VersionMinus/it|0.19}}).
* On Windows it is {{FileName|%APPDATA%\FreeCAD\Macro\}}, which is usually {{FileName|C:\Users\<username>\Appdata\Roaming\FreeCAD\Mod\}}.
* Per Windows è {{FileName|%APPDATA%\FreeCAD\Mod\}}, che di solito è {{FileName|C:\Users\<username>\Appdata\Roaming\FreeCAD\Mod\}}.
* On macOS it is usually {{FileName|/Users/<username>/Library/Preferences/FreeCAD/Mod/}}.
* Per macOS è solitamente {{FileName|/Users/<username>/Library/Application Support/FreeCAD/Mod/}}.


La directory Mod dovrebbe essere simile a questa:
The Mod directory should look like this:


{{Code|code=
{{Code|code=
Line 38: Line 36:
* Nel file Init.py si inseriscono solo alcune cose, usate anche quando FreeCAD funziona in modalità console, per esempio, gli importatori e gli esportatori di file
* Nel file Init.py si inseriscono solo alcune cose, usate anche quando FreeCAD funziona in modalità console, per esempio, gli importatori e gli esportatori di file


* Nel file InitGui.py si definisce un ambiente di lavoro che contiene un nome, un'icona e una serie di comandi di FreeCAD (vedi sotto). Nel file python si definiscono inoltre le funzioni che vengono eseguite quando si carica FreeCAD (in questa parte si cerca di fare meno lavoro possibile, in modo da non rallentare l'avvio), quelle che vengono eseguite quando si attiva l'ambiente (la parte dove si esegue la maggior parte del lavoro), e come terze quelle che servono quando l'ambiente viene disattivato (in modo da poter rimuovere le cose, se è necessario).
<div class="mw-translate-fuzzy">
* Nel file InitGui.py si definisce un ambiente di lavoro che contiene un nome, un'icona e una serie di comandi di FreeCAD (vedi sotto). Nell'ambiente si definiscono inoltre le funzioni che vengono eseguite quando si carica FreeCAD (in questa parte si cerca di fare meno lavoro possibile, in modo da non rallentare l'avvio), quelle che vengono eseguite quando si attiva l'ambiente (la parte dove si esegue la maggior parte del lavoro), e come terze quelle che servono quando l'ambiente viene disattivato (in modo da poter rimuovere le cose, se è necessario).
</div>


La struttura e il contenuto del file per un ambiente di lavoro descritto qui è il modo classico di creare un nuovo ambiente. Si può usare una leggera variazione nella struttura dei file quando si crea un nuovo ambiente in Python, questo modo alternativo è descritto più precisamente come un "ambiente di lavoro con spazio dei nomi", aprendo la possibilità di usare pip per installare l'ambiente. Entrambe le strutture funzionano, quindi è più una questione di preferenza quando si crea un nuovo ambiente di lavoro. Lo stile e la struttura per gli ambienti qui presentati sono disponibili nello spazio dei nomi globale di FreeCAD, mentre per lo stile e la struttura alternativi l'ambiente risiede in uno spazio dei nomi dedicato. Per ulteriori letture sull'argomento vedere [[Workbench creation/it#Riferimenti|Riferimenti]]
The structure and file content for a workbench described here is the classic way of creating a new workbench. One can use a slight variation in the structure of files when making a new Python workbench, that alternative way is best described as a "namespaced workbench", opening up the possibility to use pip to install the workbench. Both structures work, so it is more a question of preference when creating a new workbench. The style and structure for workbenches presented here are available in the global namespace of FreeCAD, whereas for the alternative style and structure the workbench resides in a dedicated namespace. For further readings on the topic see [[Workbench creation#Related|Related]].


<span id="C++_workbench_structure"></span>
=== Struttura del workbench in C++ ===
=== Struttura del workbench in C++ ===


Line 82: Line 79:
}}
}}


<span id="The_Init.py_file"></span>
=== Il file Init.py ===
=== Il file Init.py ===


Line 96: Line 94:
# * as published by the Free Software Foundation; either version 2 of *
# * as published by the Free Software Foundation; either version 2 of *
# * the License, or (at your option) any later version. *
# * the License, or (at your option) any later version. *
# * for detail see the LICENCE text file. *
# * for detail see the LICENSE text file. *
# * *
# * *
# * FreeCAD is distributed in the hope that it will be useful, *
# * FreeCAD is distributed in the hope that it will be useful, *
Line 111: Line 109:


FreeCAD.addImportType("My own format (*.own)", "importOwn")
FreeCAD.addImportType("My own format (*.own)", "importOwn")
FreeCAD.addExportType("My own format (*.own)", "importOwn")
FreeCAD.addExportType("My own format (*.own)", "exportOwn")
print("I am executing some stuff here when FreeCAD starts!")
print("I am executing some stuff here when FreeCAD starts!")
}}
}}


Si può scegliere qualsiasi licenza che si desidera per il proprio workbench, ma si tenga presente che se ad un certo punto si vuole vedere il proprio workbench integrato e distribuito con il codice sorgente di FreeCAD, deve essere LGPL2+ come nell'esempio sopra. Vedere la [[License/it|Licenza]].
<div class="mw-translate-fuzzy">
Per il proprio ambiente è possibile scegliere liberamente qualsiasi licenza, ma se a un certo punto si desidera vederlo integrato e distribuito con il codice sorgente di FreeCAD si deve essere consapevoli che la licenza deve essere LGPL2+, come nell'esempio precedente.
Le funzioni FreeCAD.addImportType() e addEXportType() permettono di assegnare il nome
e l'estensione di un tipo di file, e un modulo python responsabile della sua importazione. Nell'esempio precedente, un modulo "importOwn.py" gestisce i file .own. Per ulteriori esempi, vedere la pagina degli [[Code snippets/it|esempi di codice]].
</div>


The {{incode|FreeCAD.addImportType()}} and {{incode|addEXportType()}} functions allow you to give the name and extension of a file type, and a Python module responsible for its import. In the example above, an {{incode|importOwn.py}} module will handle {{incode|.own}} files. See [[Code_snippets|Code snippets]] for more examples.
Le funzioni {{incode|FreeCAD.addImportType()}} e {{incode|addEXportType()}} consentono di fornire il nome e l'estensione di un tipo di file e un modulo Python responsabile della sua importazione. Nell'esempio sopra, un modulo {{incode|importOwn.py}} gestirà i file {{incode|.own}}. Vedere [[Code_snippets/it|Frammenti di codice]] per altri esempi.


<span id="Python_workbenches"></span>
=== Python workbenches ===

<div class="mw-translate-fuzzy">
=== Ambienti di lavoro in Python ===
=== Ambienti di lavoro in Python ===

</div>
Questo è il file InitGui.py:


{{Code|code=
{{Code|code=
Line 137: Line 130:


def Initialize(self):
def Initialize(self):
"""This function is executed when FreeCAD starts"""
"""This function is executed when the workbench is first activated.
It is executed once in a FreeCAD session followed by the Activated function.
"""
import MyModuleA, MyModuleB # import here all the needed files that create your FreeCAD commands
import MyModuleA, MyModuleB # import here all the needed files that create your FreeCAD commands
self.list = ["MyCommand1", "MyCommand2"] # A list of command names created in the line above
self.list = ["MyCommand1", "MyCommand2"] # a list of command names created in the line above
self.appendToolbar("My Commands",self.list) # creates a new toolbar with your commands
self.appendToolbar("My Commands", self.list) # creates a new toolbar with your commands
self.appendMenu("My New Menu",self.list) # creates a new menu
self.appendMenu("My New Menu", self.list) # creates a new menu
self.appendMenu(["An existing Menu","My submenu"],self.list) # appends a submenu to an existing menu
self.appendMenu(["An existing Menu", "My submenu"], self.list) # appends a submenu to an existing menu


def Activated(self):
def Activated(self):
"""This function is executed when the workbench is activated"""
"""This function is executed whenever the workbench is activated"""
return
return


def Deactivated(self):
def Deactivated(self):
"""This function is executed when the workbench is deactivated"""
"""This function is executed whenever the workbench is deactivated"""
return
return


def ContextMenu(self, recipient):
def ContextMenu(self, recipient):
"""This is executed whenever the user right-clicks on screen"""
"""This function is executed whenever the user right-clicks on screen"""
# "recipient" will be either "view" or "tree"
# "recipient" will be either "view" or "tree"
self.appendContextMenu("My commands",self.list) # add commands to the context menu
self.appendContextMenu("My commands", self.list) # add commands to the context menu


def GetClassName(self):
def GetClassName(self):
Line 165: Line 160:
}}
}}


A parte questo, si può fare tutto ciò che si vuole: si potrebbe mettere tutto il codice del workbench all'interno di InitGui.py se si vuole, ma di solito è più conveniente posizionare le diverse funzioni dell'ambiente in file separati. Così i file sono più piccoli e più facili da leggere. Poi si importano i file in InitGui.py. È possibile organizzare i file nel modo desiderato, un buon esempio di organizzazione è un file per ogni comando di FreeCAD che si aggiunge.
<div class="mw-translate-fuzzy">
Oltre a questo, si può fare tutto quello che si vuole: si potrebbe mettere tutto il codice del workbench all'interno di InitGui.py se si vuole, ma di solito è più conveniente posizionare le diverse funzioni dell'ambiente in file separati. Così i file sono più piccoli e più facili da leggere. Poi si importano i file nel file InitGui.py. È possibile organizzare i file nel modo desiderato, un buon esempio di organizzazione è un file per ogni comando di FreeCAD che si aggiunge.
</div>


====Preferences====
<span id="Preferences"></span>
====Preferenze====


Si può aggiungere una pagina Preferenze per il proprio ambiente di lavoro Python. Le pagine delle preferenze cercano un'icona di preferenza con un nome specifico nel sistema Qt Resource. Se l'icona non è nel sistema di risorse o non ha il nome corretto, l'icona non verrà visualizzata nella pagina Preferenze.
You can add a Preferences page for your Python workbench. The Preferences pages look for a preference icon with a specific name in the Qt Resource system. If your icon isn't in the resource system or doesn't have the correct name, your icon won't appear on the Preferences page.


Aggiunta dell'icona del proprio workbench:
Adding your workbench icon:
* the preferences icon needs to be named "preferences-" + "modulename" + ".svg" (all lowercase)
* l'icona delle preferenze deve essere chiamata "preferences-" + "modulename" + ".svg" (tutto in minuscolo)
* creare un file qrc contenente tutti i nomi delle icone
* make a qrc file containing all icon names
* in the main *.py directory, run pyside-rcc -o myResources.py myqrc.qrc
* nella directory principale *.py, eseguire pyside-rcc -o myResources.py myqrc.qrc
* in InitGui.py, add import myResource(.py)
* in InitGui.py, aggiungere import myResource(.py)
* update your repository(git) with myResources.py and myqrc.qrc
* aggiornare il tuo repository (git) con myResources.py e myqrc.qrc


Si dovranno ripetere i passaggi se si aggiungono o modificano le icone.
You'll need to redo the steps if you add/change icons.


@kbwbe has created a nice script to compile resources for the A2Plus workbench. See below.
@kbwbe ha creato un buon script per compilare risorse per il workbench A2Plus. Vedere sotto.


Aggiunta delle tue pagine delle preferenze:
Adding your preference page(s):
* You need to compile the Qt designer plugin that allows you to add preference settings with [[Compile_on_Linux#Qt_designer_plugin|Qt Designer]]
* Si deve compilare il plug-in Qt designer che consente di aggiungere le impostazioni delle preferenze con [[Compile_on_Linux/it#Plug-in Qt designer|Qt Designer]]
* Create a blank widget in Qt Designer (no buttons or anything)
* Creare un widget vuoto in Qt Designer (nessun pulsante o altro)
* Design your preference page, any setting that must be saved (preferences) must be one of the Gui::Pref* widgets that were added by the plugin)
* Progettare tua pagina delle preferenze, qualsiasi impostazione che deve essere salvata (preferenza) deve essere uno dei widget Gui::Pref* che sono stati aggiunti dal plugin)
* In any of those, make sure you fill the PrefName (the name of your preference value) and PrefPath (ex: Mod/MyWorkbenchName), which will save your value under BaseApp/Preferences/Mod/MyWorkbenchName
* In ognuno di questi, assicurarsi d'inserire PrefName (il nome del tuo valore di preferenza) e PrefPath (es: Mod/MyWorkbenchName), che salverà il tuo valore in BaseApp/Preferences/Mod/MyWorkbenchName
* Save the ui file in your workbench, make sure it's handled by cmake
* Salvare il file ui nel proprio ambiente, assicurarsi che sia gestito da cmake
* In your workbench, for ex. inside the InitGui file, inside the Initialize method (but any other place works too), add: FreeCADGui.addPreferencePage("/path/to/myUiFile.ui","MyGroup"), "MyGroup" being one of the preferences groups on the left. FreeCAD will automatically look for a "preferences-mygroup.svg" file in its known locations (which you can extend with FreeCADGui.addIconPath())
* Nel proprio banco di lavoro, ad es. all'interno del file InitGui, all'interno del metodo Initialize (ma funziona anche in qualsiasi altro posto), aggiungere: FreeCADGui.addPreferencePage("/path/to/myUiFile.ui","MyGroup"), "MyGroup" essendo uno dei gruppi di preferenze su la sinistra. FreeCAD cercherà automaticamente un file "preferences-mygroup.svg" nelle sue posizioni note (che si può estendere con FreeCADGui.addIconPath())
* Make sure the addPreferencePage() method is called only once, otherwise your pref page will be added several times
* Assicurarsi che il metodo addPreferencePage() sia chiamato solo una volta, altrimenti la pagina pref verrà aggiunta più volte


====Distribution====
<span id="Distribution"></span>
====Distribuzione====


To distribute your Python workbench, you may either simply host the files in some location and instruct your users to download them and place them in their Mod directory manually, or you may host them in an online git repository (GitHub, GitLab, and Debian Salsa are currently supported locations) and configure them for the [[Std_AddonMgr|Addon Manager]] to install. Instructions for inclusion on FreeCAD's official Addons list can be found on the [https://github.com/FreeCAD/FreeCAD-addons/blob/master/README.md FreeCAD Addons GitHub repository]. To use the Addon Manager, a [[Package_Metadata|package.xml metadata file]] should be included, which instructs the Addon Manager how to find your workbench's icon, and allows display of a description, version number, etc. It can also be used to specify other external Addons that your Workbench either depends on, is blocked by, or is intended to replace.
Per distribuire il proprio workbench Python, si può semplicemente ospitare i file in una posizione e istruire gli utenti a scaricarli e inserirli manualmente nella loro directory Mod, oppure si possono ospitare in un repository git online (GitHub, GitLab, Framagit e Debian Salsa sono posizioni attualmente supportate) e configurarle per l'installazione con l'[[Std_AddonMgr/it|Addon Manager]]. Le istruzioni per l'inclusione nell'elenco dei componenti aggiuntivi ufficiali di FreeCAD sono disponibili nel [https://github.com/FreeCAD/FreeCAD-addons/blob/master/README.md repository GitHub dei componenti aggiuntivi di FreeCAD]. Per utilizzare Addon Manager, è necessario includere un [[Package_Metadata/it|package.xml metadata file]], che istruisce Addon Manager su come trovare l'icona del proprio ambiente e consente la visualizzazione di una descrizione, numero di versione, ecc. Può anche essere utilizzato per specificare altri workbench o pacchetti Python da cui dipende l'ambiente in cui è bloccato o che è destinato a sostituire.


Per una guida rapida su come creare un file package.xml di base e aggiungere un workbench all'[[Std_AddonMgr/it|Addon Manager]] vedere: [[Add_Workbench_to_Addon_Manager/it|Aggiungere Workbench in Addon Manager]].
Optionally, you can include a file called metadata.txt describing your workbench's external dependencies (on either other Addons, Workbenches, or Python modules). The format of this file is plain text, with three optional lines:

Facoltativamente, si può includere a parte un file di metadati che descriva le dipendenze Python. Questo può essere un file chiamato metadata.txt che descrive le dipendenze esterne dell'ambiente (su altri componenti aggiuntivi, workbench o moduli Python) o un [https://pip.pypa.io/en/latest/reference/requirements-file -format/ requirements.txt] descrivendo le dipendenze Python. Si noti che se si utilizza un file requirements.txt, solo i nomi dei pacchetti specificati vengono utilizzati per la risoluzione delle dipendenze: le opzioni del comando pip, le opzioni di inclusione e le informazioni sulla versione non sono supportate da Addon Manager. Gli utenti possono eseguire manualmente il file dei requisiti utilizzando pip se tali funzionalità sono richieste.

Il formato del file metadata.txt è testo semplice, con tre righe facoltative:


{{Code|code=
{{Code|code=
Line 205: Line 204:
}}
}}


Each line should consist of a comma-separated list of items your Workbench depends on. Workbenches may be either an internal FreeCAD Workbench, e.g. "FEM", or an external Addon, for example "Curves". The required and optional Python libraries should be specified with their canonical Python names, such as you would use with {{incode|pip install}}. For example:
Ogni riga dovrebbe consistere in un elenco separato da virgole di elementi da cui dipende l'Ambiente. Gli ambienti di lavoro possono essere un ambiente di lavoro interno di FreeCAD, ad es. "FEM", o un Addon esterno, ad esempio "Curve". Le librerie Python obbligatorie e facoltative dovrebbero essere specificate con i loro nomi Python canonici, come si userebbe con {{incode|pip install}}. Per esempio:


{{Code|code=
{{Code|code=
Line 213: Line 212:
}}
}}


Si può anche includere uno script che viene eseguito quando il pacchetto viene disinstallato. Questo è un file chiamato "uninstall.py" che si trova al livello superiore del componente aggiuntivo. Viene eseguito quando un utente disinstalla il componente aggiuntivo utilizzando Addon Manager. Si usa per ripulire tutto ciò che il componente aggiuntivo potrebbe aver fatto al sistema degli utenti e che non dovrebbe persistere quando il componente aggiuntivo viene rimosso (ad esempio, rimuovere i file della cache, ecc.).

Per assicurarti che il proprio componente aggiuntivo venga letto correttamente da Addon Manager, si può abilitare una "modalità sviluppatore" in cui Addon Manager esamina tutti i componenti aggiuntivi disponibili e garantisce che i loro metadati contengano gli elementi richiesti. Per abilitare questa modalità selezionare: {{MenuCommand|Modifica → Preferenze... → Gestore componenti aggiuntivi → Opzioni gestore componenti aggiuntivi → Modalità sviluppatore componenti aggiuntivi}}, vedere l'[[Preferences_Editor/it#Opzioni_di_Addon_manager|Editor delle preferenze]].

<span id="C++_workbenches"></span>
===Workbench in C++===
===Workbench in C++===


<div class="mw-translate-fuzzy">
Quando si vuole codificare l'ambiente in C ++, probabilmente si vuole anche codificare la definizione dell'ambiente stesso in C ++ (anche se non è necessario: si potrebbe anche codificare solo gli strumenti in C++, e lasciare la definizione dell'ambiente in python). In tal caso, il file InitGui.py diventa molto semplice: Può contenere una sola riga:
Quando si vuole codificare l'ambiente in C ++, probabilmente si vuole anche codificare la definizione dell'ambiente stesso in C ++ (anche se non è necessario: si potrebbe anche codificare solo gli strumenti in C++, e lasciare la definizione dell'ambiente in python). In tal caso, il file InitGui.py diventa molto semplice: Può contenere una sola riga:
</div>


{{Code|code=import MyModuleGui}}
{{Code|code=import MyModuleGui}}


<div class="mw-translate-fuzzy">
dove MyModule è l'ambiente completo in C++, inclusi i comandi e la definizione dell'ambiente.
dove MyModule è l'ambiente completo in C++, inclusi i comandi e la definizione dell'ambiente.
</div>


<div class="mw-translate-fuzzy">
La codificazione dei workbenches in C++ funziona in modo molto simile. Questo è un tipico file Workbench.cpp da includere nella parte Gui del modulo:
La codificazione dei workbenches in C++ funziona in modo molto simile. Questo è un tipico file Workbench.cpp da includere nella parte Gui del modulo:
</div>


{{Code|code=
{{Code|code=
Line 249: Line 247:
}}
}}


====Preferences====
<span id="Preferences"></span>
====Preferenze====

Si può anche aggiungere una pagina delle preferenze per i workbench C++. I passaggi sono simili a quelli per Python.

<span id="Distribution"></span>
====Distribuzione====


Ci sono due opzioni per distribuire un workbench C++, si può ospitare da se le versioni precompilate per i diversi sistemi operativi oppure si può richiedere che il codice venga unito al codice sorgente di FreeCAD. Come accennato in precedenza, ciò richiede una licenza LGPL2+ e si deve prima presentare il proprio workbench alla comunità nel [https://forum.freecad.org forum di FreeCAD] per la revisione.
You can add a Preferences page for C++ workbenches too. The steps are similar to those for Python.


<span id="FreeCAD_commands"></span>
== I comandi di FreeCAD ==
== I comandi di FreeCAD ==


<div class="mw-translate-fuzzy">
I comandi FreeCAD sono gli elementi di base dell'interfaccia di FreeCAD. Possono apparire come un pulsanti sulla barra degli strumenti, e come voce di menu. Ma sono lo stesso comando. Un comando è una semplice classe Python, che deve contenere un paio di attributi predefiniti e le funzioni che definiscono il nome del comando, la sua icona, e cosa fare quando viene attivato il comando.
I comandi FreeCAD sono gli elementi di base dell'interfaccia di FreeCAD. Possono apparire come un pulsanti sulla barra degli strumenti, e come voce di menu. Ma sono lo stesso comando. Un comando è una semplice classe Python, che deve contenere un paio di attributi predefiniti e le funzioni che definiscono il nome del comando, la sua icona, e cosa fare quando viene attivato il comando.
</div>


<span id="Python_command_definition"></span>
=== Definizione dei comandi Python ===
=== Definizione dei comandi Python ===


Line 283: Line 287:
}}
}}


<span id="C++_command_definition"></span>
=== Definizione dei comandi C++ ===
=== Definizione dei comandi C++ ===


Allo stesso modo, è possibile codificare i comandi in C++, in genere hanno un file Commands.cpp nel modulo Gui. Questo è un tipico file Commands.cpp:
Allo stesso modo, è possibile codificare i comandi in C++, in genere in un file Commands.cpp nel modulo Gui. Questo è un tipico file Commands.cpp:


{{Code|code=DEF_STD_CMD_A(CmdMyCommand);
{{Code|code=DEF_STD_CMD_A(CmdMyCommand);
Line 324: Line 329:
}}
}}


<span id="&quot;Compiling&quot;_your_resource_file"></span>
=="Compiling" your resource file==
=="Compilazione" del file di risorse==


compileA2pResources.py from the A2Plus workbench:
compileA2pResources.py dall'ambiente A2Plus:


{{Code|code=#!/usr/bin/env python
{{Code|code=#!/usr/bin/env python
Line 340: Line 346:
#* as published by the Free Software Foundation; either version 2 of *
#* as published by the Free Software Foundation; either version 2 of *
#* the License, or (at your option) any later version. *
#* the License, or (at your option) any later version. *
#* for detail see the LICENCE text file. *
#* for detail see the LICENSE text file. *
#* *
#* *
#* This program is distributed in the hope that it will be useful, *
#* This program is distributed in the hope that it will be useful, *
Line 386: Line 392:
}}
}}


== Related ==
<span id="Related"></span>
== Riferimenti ==


* [[Translating_an_external_workbench|Translating an external workbench]]
* [[Translating_an_external_workbench/it|Traduzione di un ambiente di lavoro esterno]]
* [https://forum.freecadweb.org/viewtopic.php?t=47460 Namespaced Workbenches - discussion]
* [https://forum.freecadweb.org/viewtopic.php?t=47460 Forum discussion: Namespaced Workbenches]
* [https://github.com/FreeCAD/freecad.workbench_starterkit freecad.workbench_starterkit]
* [https://github.com/FreeCAD/freecad.workbench_starterkit freecad.workbench_starterkit]




{{Docnav
{{Docnav/it
|[[Localisation|Localisation]]
|[[Localisation/it|Localizzazione]]
|[[Extra_python_modules|Extra Python modules]]
|[[Extra_python_modules/it|Moduli Python aggiuntivi]]
}}
}}



Latest revision as of 07:09, 7 April 2024

Introduzione

Questa pagina da indicazioni su come aggiungere un nuovo ambiente di lavoro all'interfaccia di FreeCAD. Gli Ambienti di Lavoro sono contenitori per i comandi di FreeCAD. Possono essere codificati in Python, in C++ o in un mix di entrambi, il che ha il vantaggio di unire la velocità del C++ alla flessibilità di Python. In tutti i casi, tuttavia, l'ambiente verrà avviato da un set di due file Python. Possono essere ambienti di lavoro "interni", inclusi nella distribuzione di FreeCAD, o ambienti di lavoro "esterni", distribuiti tramite l'Addon Manager o installati manualmente scaricandoli da qualche repository online. Gli Ambienti di lavoro interni possono essere codificati in C++, Python o una combinazione dei due, mentre i workbench esterni devono essere solo in Python.

La struttura dell'Ambiente di lavoro

È necessaria una cartella, con qualsiasi nome si voglia, collocata nella directory Mod dell'utente, con un file Init.py e, facoltativamente, un file InitGui.py. Il file Init viene eseguito all'avvio di FreeCAD e il file InitGui.py viene eseguito immediatamente dopo, ma solo quando FreeCAD si avvia in modalità GUI. Questo è tutto ciò che serve a FreeCAD per trovare l'ambiente di lavoro all'avvio e aggiungerlo alla propria interfaccia.

La cartella utente Mod è una sottocartella della cartella dei dati dell'applicazione utente (si può trovare quest'ultima digitando App.getUserAppDataDir() nella console Python):

  • Per Linux è solitamente /home/<username>/.local/share/FreeCAD/Mod/ (versione 0.20 e superiori) o /home/<username>/.FreeCAD/Mod/ (versione 0.19 e precedenti).
  • Per Windows è %APPDATA%\FreeCAD\Mod\, che di solito è C:\Users\<username>\Appdata\Roaming\FreeCAD\Mod\.
  • Per macOS è solitamente /Users/<username>/Library/Application Support/FreeCAD/Mod/.

La directory Mod dovrebbe essere simile a questa:

/Mod/
 +-- MyWorkbench/
     +-- Init.py
     +-- InitGui.py

All'interno questi file si può fare quello che si vuole. Di solito vengono utilizzati in questo modo:

  • Nel file Init.py si inseriscono solo alcune cose, usate anche quando FreeCAD funziona in modalità console, per esempio, gli importatori e gli esportatori di file
  • Nel file InitGui.py si definisce un ambiente di lavoro che contiene un nome, un'icona e una serie di comandi di FreeCAD (vedi sotto). Nel file python si definiscono inoltre le funzioni che vengono eseguite quando si carica FreeCAD (in questa parte si cerca di fare meno lavoro possibile, in modo da non rallentare l'avvio), quelle che vengono eseguite quando si attiva l'ambiente (la parte dove si esegue la maggior parte del lavoro), e come terze quelle che servono quando l'ambiente viene disattivato (in modo da poter rimuovere le cose, se è necessario).

La struttura e il contenuto del file per un ambiente di lavoro descritto qui è il modo classico di creare un nuovo ambiente. Si può usare una leggera variazione nella struttura dei file quando si crea un nuovo ambiente in Python, questo modo alternativo è descritto più precisamente come un "ambiente di lavoro con spazio dei nomi", aprendo la possibilità di usare pip per installare l'ambiente. Entrambe le strutture funzionano, quindi è più una questione di preferenza quando si crea un nuovo ambiente di lavoro. Lo stile e la struttura per gli ambienti qui presentati sono disponibili nello spazio dei nomi globale di FreeCAD, mentre per lo stile e la struttura alternativi l'ambiente risiede in uno spazio dei nomi dedicato. Per ulteriori letture sull'argomento vedere Riferimenti

Struttura del workbench in C++

Per codificare l'ambiente in python, non è necessario usare particolari attenzioni, è possibile inserire semplicemente gli altri file python insieme ai file Init.py e InitGui.py. Invece, quando si lavora in C++ si deve avere maggiori attenzioni, e iniziare rispettando una regola fondamentale di FreeCAD: separare la parte App dell'ambiente, quella che può essere eseguita in modalità console, senza alcun elemento GUI, dalla parte Gui, che è quella che viene caricata solo quando FreeCAD funziona completo del suo ambiente GUI. Quindi, quando si crea un ambiente in C++, in realtà si creano probabilmente due moduli, un App e un Gui. Questi due moduli devono naturalmente essere richiamabili in python. Ogni modulo di FreeCAD (App o Gui) consiste, per lo meno, di un modulo con un file init. Questo è un tipico file AppMyModuleGui.cpp:

extern "C" {
    void MyModuleGuiExport initMyModuleGui()  
    {
         if (!Gui::Application::Instance) {
            PyErr_SetString(PyExc_ImportError, "Cannot load Gui module in console application.");
            return;
        }
        try {
            // import other modules this one depends on
            Base::Interpreter().runString("import PartGui");
            // run some python code in the console
            Base::Interpreter().runString("print('welcome to my module!')");
        }
        catch(const Base::Exception& e) {
            PyErr_SetString(PyExc_ImportError, e.what());
            return;
        }
        (void) Py_InitModule("MyModuleGui", MyModuleGui_Import_methods);   /* mod name, table ptr */
        Base::Console().Log("Loading GUI of MyModule... done\n");
    
        // initializes the FreeCAD commands (in another cpp file)
        CreateMyModuleCommands();
    
        // initializes workbench and object definitions
        MyModuleGui::Workbench::init();
        MyModuleGui::ViewProviderSomeCustomObject::init();
    
         // add resources and reloads the translators
        loadMyModuleResource();
    }
}

Il file Init.py

"""FreeCAD init script of XXX module"""

# ***************************************************************************
# *   Copyright (c) 2015 John Doe john@doe.com                              *   
# *                                                                         *
# *   This file is part of the FreeCAD CAx development system.              *
# *                                                                         *
# *   This program is free software; you can redistribute it and/or modify  *
# *   it under the terms of the GNU Lesser General Public License (LGPL)    *
# *   as published by the Free Software Foundation; either version 2 of     *
# *   the License, or (at your option) any later version.                   *
# *   for detail see the LICENSE text file.                                 *
# *                                                                         *
# *   FreeCAD is distributed in the hope that it will be useful,            *
# *   but WITHOUT ANY WARRANTY; without even the implied warranty of        *
# *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *
# *   GNU Lesser General Public License for more details.                   *
# *                                                                         *
# *   You should have received a copy of the GNU Library General Public     *
# *   License along with FreeCAD; if not, write to the Free Software        *
# *   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  *
# *   USA                                                                   *
# *                                                                         *
# ***************************************************************************/

FreeCAD.addImportType("My own format (*.own)", "importOwn")
FreeCAD.addExportType("My own format (*.own)", "exportOwn")
print("I am executing some stuff here when FreeCAD starts!")

Si può scegliere qualsiasi licenza che si desidera per il proprio workbench, ma si tenga presente che se ad un certo punto si vuole vedere il proprio workbench integrato e distribuito con il codice sorgente di FreeCAD, deve essere LGPL2+ come nell'esempio sopra. Vedere la Licenza.

Le funzioni FreeCAD.addImportType() e addEXportType() consentono di fornire il nome e l'estensione di un tipo di file e un modulo Python responsabile della sua importazione. Nell'esempio sopra, un modulo importOwn.py gestirà i file .own. Vedere Frammenti di codice per altri esempi.

Ambienti di lavoro in Python

Questo è il file InitGui.py:

class MyWorkbench (Workbench):

    MenuText = "My Workbench"
    ToolTip = "A description of my workbench"
    Icon = """paste here the contents of a 16x16 xpm icon"""

    def Initialize(self):
        """This function is executed when the workbench is first activated.
        It is executed once in a FreeCAD session followed by the Activated function.
        """
        import MyModuleA, MyModuleB # import here all the needed files that create your FreeCAD commands
        self.list = ["MyCommand1", "MyCommand2"] # a list of command names created in the line above
        self.appendToolbar("My Commands", self.list) # creates a new toolbar with your commands
        self.appendMenu("My New Menu", self.list) # creates a new menu
        self.appendMenu(["An existing Menu", "My submenu"], self.list) # appends a submenu to an existing menu

    def Activated(self):
        """This function is executed whenever the workbench is activated"""
        return

    def Deactivated(self):
        """This function is executed whenever the workbench is deactivated"""
        return

    def ContextMenu(self, recipient):
        """This function is executed whenever the user right-clicks on screen"""
        # "recipient" will be either "view" or "tree"
        self.appendContextMenu("My commands", self.list) # add commands to the context menu

    def GetClassName(self): 
        # This function is mandatory if this is a full Python workbench
        # This is not a template, the returned string should be exactly "Gui::PythonWorkbench"
        return "Gui::PythonWorkbench"
       
Gui.addWorkbench(MyWorkbench())

A parte questo, si può fare tutto ciò che si vuole: si potrebbe mettere tutto il codice del workbench all'interno di InitGui.py se si vuole, ma di solito è più conveniente posizionare le diverse funzioni dell'ambiente in file separati. Così i file sono più piccoli e più facili da leggere. Poi si importano i file in InitGui.py. È possibile organizzare i file nel modo desiderato, un buon esempio di organizzazione è un file per ogni comando di FreeCAD che si aggiunge.

Preferenze

Si può aggiungere una pagina Preferenze per il proprio ambiente di lavoro Python. Le pagine delle preferenze cercano un'icona di preferenza con un nome specifico nel sistema Qt Resource. Se l'icona non è nel sistema di risorse o non ha il nome corretto, l'icona non verrà visualizzata nella pagina Preferenze.

Aggiunta dell'icona del proprio workbench:

  • l'icona delle preferenze deve essere chiamata "preferences-" + "modulename" + ".svg" (tutto in minuscolo)
  • creare un file qrc contenente tutti i nomi delle icone
  • nella directory principale *.py, eseguire pyside-rcc -o myResources.py myqrc.qrc
  • in InitGui.py, aggiungere import myResource(.py)
  • aggiornare il tuo repository (git) con myResources.py e myqrc.qrc

Si dovranno ripetere i passaggi se si aggiungono o modificano le icone.

@kbwbe ha creato un buon script per compilare risorse per il workbench A2Plus. Vedere sotto.

Aggiunta delle tue pagine delle preferenze:

  • Si deve compilare il plug-in Qt designer che consente di aggiungere le impostazioni delle preferenze con Qt Designer
  • Creare un widget vuoto in Qt Designer (nessun pulsante o altro)
  • Progettare tua pagina delle preferenze, qualsiasi impostazione che deve essere salvata (preferenza) deve essere uno dei widget Gui::Pref* che sono stati aggiunti dal plugin)
  • In ognuno di questi, assicurarsi d'inserire PrefName (il nome del tuo valore di preferenza) e PrefPath (es: Mod/MyWorkbenchName), che salverà il tuo valore in BaseApp/Preferences/Mod/MyWorkbenchName
  • Salvare il file ui nel proprio ambiente, assicurarsi che sia gestito da cmake
  • Nel proprio banco di lavoro, ad es. all'interno del file InitGui, all'interno del metodo Initialize (ma funziona anche in qualsiasi altro posto), aggiungere: FreeCADGui.addPreferencePage("/path/to/myUiFile.ui","MyGroup"), "MyGroup" essendo uno dei gruppi di preferenze su la sinistra. FreeCAD cercherà automaticamente un file "preferences-mygroup.svg" nelle sue posizioni note (che si può estendere con FreeCADGui.addIconPath())
  • Assicurarsi che il metodo addPreferencePage() sia chiamato solo una volta, altrimenti la pagina pref verrà aggiunta più volte

Distribuzione

Per distribuire il proprio workbench Python, si può semplicemente ospitare i file in una posizione e istruire gli utenti a scaricarli e inserirli manualmente nella loro directory Mod, oppure si possono ospitare in un repository git online (GitHub, GitLab, Framagit e Debian Salsa sono posizioni attualmente supportate) e configurarle per l'installazione con l'Addon Manager. Le istruzioni per l'inclusione nell'elenco dei componenti aggiuntivi ufficiali di FreeCAD sono disponibili nel repository GitHub dei componenti aggiuntivi di FreeCAD. Per utilizzare Addon Manager, è necessario includere un package.xml metadata file, che istruisce Addon Manager su come trovare l'icona del proprio ambiente e consente la visualizzazione di una descrizione, numero di versione, ecc. Può anche essere utilizzato per specificare altri workbench o pacchetti Python da cui dipende l'ambiente in cui è bloccato o che è destinato a sostituire.

Per una guida rapida su come creare un file package.xml di base e aggiungere un workbench all'Addon Manager vedere: Aggiungere Workbench in Addon Manager.

Facoltativamente, si può includere a parte un file di metadati che descriva le dipendenze Python. Questo può essere un file chiamato metadata.txt che descrive le dipendenze esterne dell'ambiente (su altri componenti aggiuntivi, workbench o moduli Python) o un -format/ requirements.txt descrivendo le dipendenze Python. Si noti che se si utilizza un file requirements.txt, solo i nomi dei pacchetti specificati vengono utilizzati per la risoluzione delle dipendenze: le opzioni del comando pip, le opzioni di inclusione e le informazioni sulla versione non sono supportate da Addon Manager. Gli utenti possono eseguire manualmente il file dei requisiti utilizzando pip se tali funzionalità sono richieste.

Il formato del file metadata.txt è testo semplice, con tre righe facoltative:

workbenches=
pylibs=
optionalpylibs=

Ogni riga dovrebbe consistere in un elenco separato da virgole di elementi da cui dipende l'Ambiente. Gli ambienti di lavoro possono essere un ambiente di lavoro interno di FreeCAD, ad es. "FEM", o un Addon esterno, ad esempio "Curve". Le librerie Python obbligatorie e facoltative dovrebbero essere specificate con i loro nomi Python canonici, come si userebbe con pip install. Per esempio:

workbenches=FEM,Curves
pylibs=ezdxf
optionalpylibs=metadata,git

Si può anche includere uno script che viene eseguito quando il pacchetto viene disinstallato. Questo è un file chiamato "uninstall.py" che si trova al livello superiore del componente aggiuntivo. Viene eseguito quando un utente disinstalla il componente aggiuntivo utilizzando Addon Manager. Si usa per ripulire tutto ciò che il componente aggiuntivo potrebbe aver fatto al sistema degli utenti e che non dovrebbe persistere quando il componente aggiuntivo viene rimosso (ad esempio, rimuovere i file della cache, ecc.).

Per assicurarti che il proprio componente aggiuntivo venga letto correttamente da Addon Manager, si può abilitare una "modalità sviluppatore" in cui Addon Manager esamina tutti i componenti aggiuntivi disponibili e garantisce che i loro metadati contengano gli elementi richiesti. Per abilitare questa modalità selezionare: Modifica → Preferenze... → Gestore componenti aggiuntivi → Opzioni gestore componenti aggiuntivi → Modalità sviluppatore componenti aggiuntivi, vedere l'Editor delle preferenze.

Workbench in C++

Quando si vuole codificare l'ambiente in C ++, probabilmente si vuole anche codificare la definizione dell'ambiente stesso in C ++ (anche se non è necessario: si potrebbe anche codificare solo gli strumenti in C++, e lasciare la definizione dell'ambiente in python). In tal caso, il file InitGui.py diventa molto semplice: Può contenere una sola riga:

import MyModuleGui

dove MyModule è l'ambiente completo in C++, inclusi i comandi e la definizione dell'ambiente.

La codificazione dei workbenches in C++ funziona in modo molto simile. Questo è un tipico file Workbench.cpp da includere nella parte Gui del modulo:

namespace MyModuleGui {
    class MyModuleGuiExport Workbench : public Gui::StdWorkbench
    {
        TYPESYSTEM_HEADER();

    public:
        Workbench();
        virtual ~Workbench();

        virtual void activated();
        virtual void deactivated();

    protected:
        Gui::ToolBarItem* setupToolBars() const;
        Gui::MenuItem*    setupMenuBar() const;
    };
}

Preferenze

Si può anche aggiungere una pagina delle preferenze per i workbench C++. I passaggi sono simili a quelli per Python.

Distribuzione

Ci sono due opzioni per distribuire un workbench C++, si può ospitare da se le versioni precompilate per i diversi sistemi operativi oppure si può richiedere che il codice venga unito al codice sorgente di FreeCAD. Come accennato in precedenza, ciò richiede una licenza LGPL2+ e si deve prima presentare il proprio workbench alla comunità nel forum di FreeCAD per la revisione.

I comandi di FreeCAD

I comandi FreeCAD sono gli elementi di base dell'interfaccia di FreeCAD. Possono apparire come un pulsanti sulla barra degli strumenti, e come voce di menu. Ma sono lo stesso comando. Un comando è una semplice classe Python, che deve contenere un paio di attributi predefiniti e le funzioni che definiscono il nome del comando, la sua icona, e cosa fare quando viene attivato il comando.

Definizione dei comandi Python

class My_Command_Class():
    """My new command"""

    def GetResources(self):
        return {"Pixmap"  : "My_Command_Icon", # the name of a svg file available in the resources
                "Accel"   : "Shift+S", # a default shortcut (optional)
                "MenuText": "My New Command",
                "ToolTip" : "What my new command does"}

    def Activated(self):
        """Do something here"""
        return

    def IsActive(self):
        """Here you can define if the command must be active or not (greyed) if certain conditions
        are met or not. This function is optional."""
        return True

FreeCADGui.addCommand("My_Command", My_Command_Class())

Definizione dei comandi C++

Allo stesso modo, è possibile codificare i comandi in C++, in genere in un file Commands.cpp nel modulo Gui. Questo è un tipico file Commands.cpp:

DEF_STD_CMD_A(CmdMyCommand);

CmdMyCommand::CmdMyCommand()
  :Command("My_Command")
{
  sAppModule    = "MyModule";
  sGroup        = QT_TR_NOOP("MyModule");
  sMenuText     = QT_TR_NOOP("Runs my command...");
  sToolTipText  = QT_TR_NOOP("Describes what my command does");
  sWhatsThis    = QT_TR_NOOP("Describes what my command does");
  sStatusTip    = QT_TR_NOOP("Describes what my command does");
  sPixmap       = "some_svg_icon_from_my_resource";
}

void CmdMyCommand::activated(int iMsg)
{
    openCommand("My Command");
    doCommand(Doc,"print('Hello, world!')");
    commitCommand();
    updateActive();
}

bool CmdMyCommand::isActive(void)
{
  if( getActiveGuiDocument() )
    return true;
  else
    return false;
}

void CreateMyModuleCommands(void)
{
    Gui::CommandManager &rcCmdMgr = Gui::Application::Instance->commandManager();
    rcCmdMgr.addCommand(new CmdMyCommand());
}

"Compilazione" del file di risorse

compileA2pResources.py dall'ambiente A2Plus:

#!/usr/bin/env python
# -*- coding: utf-8 -*-
#***************************************************************************
#*                                                                         *
#*   Copyright (c) 2019 kbwbe                                              *
#*                                                                         *
#*   Portions of code based on hamish's assembly 2                         *
#*                                                                         *
#*   This program is free software; you can redistribute it and/or modify  *
#*   it under the terms of the GNU Lesser General Public License (LGPL)    *
#*   as published by the Free Software Foundation; either version 2 of     *
#*   the License, or (at your option) any later version.                   *
#*   for detail see the LICENSE text file.                                 *
#*                                                                         *
#*   This program is distributed in the hope that it will be useful,       *
#*   but WITHOUT ANY WARRANTY; without even the implied warranty of        *
#*   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *
#*   GNU Library General Public License for more details.                  *
#*                                                                         *
#*   You should have received a copy of the GNU Library General Public     *
#*   License along with this program; if not, write to the Free Software   *
#*   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  *
#*   USA                                                                   *
#*                                                                         *
#***************************************************************************

# This script compiles the A2plus icons for py2 and py3
# For Linux only
# Start this file in A2plus main directory
# Make sure pyside-rcc is installed

import os, glob

qrc_filename = 'temp.qrc'
if os.path.exists(qrc_filename):
    os.remove(qrc_filename)

qrc = '''<RCC>
\t<qresource prefix="/">'''
for fn in glob.glob('./icons/*.svg'):
    qrc = qrc + '\n\t\t<file>%s</file>' % fn
qrc = qrc + '''\n\t</qresource>
</RCC>'''

print(qrc)

f = open(qrc_filename,'w')
f.write(qrc)
f.close()

os.system(
    'pyside-rcc -o a2p_Resources2.py {}'.format(qrc_filename))
os.system(
    'pyside-rcc -py3 -o a2p_Resources3.py {}'.format(qrc_filename))

os.remove(qrc_filename)

Riferimenti