FreeCAD-Doc/localwiki/Workbench_creation-it.html
2018-07-19 18:47:02 -05:00

233 lines
14 KiB
HTML

<html><head><title>Workbench creation/it</title><meta http-equiv="Content-Type" content="text/html; charset=utf-8"><link type='text/css' href='wiki.css' rel='stylesheet'></head><body><h1>Workbench creation/it</h1></div>
<div id="mw-content-text" lang="it" dir="ltr" class="mw-content-ltr"><hr/><div class="mw-parser-output"><p>Questa pagina spiega come aggiungere un nuovo ambiente di lavoro (Workbench) all'interfaccia di FreeCAD. Gli <a href="https://www.freecadweb.org/wiki/index.php?title=Workbenches/it" title="Workbenches/it">Workbenches</a> 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.
</p>
<div id="toc" class="toc"><div class="toctitle"><h2>Contents</h2></div>
<ul>
<li class="toclevel-1 tocsection-1"><a href="#La_struttura_del_workbench"><span class="tocnumber">1</span> <span class="toctext">La struttura del workbench</span></a>
<ul>
<li class="toclevel-2 tocsection-2"><a href="#Struttura_del_workbench_in_C.2B.2B"><span class="tocnumber">1.1</span> <span class="toctext">Struttura del workbench in C++</span></a></li>
<li class="toclevel-2 tocsection-3"><a href="#Il_file_Init.py"><span class="tocnumber">1.2</span> <span class="toctext">Il file Init.py</span></a></li>
<li class="toclevel-2 tocsection-4"><a href="#Ambienti_di_lavoro_in_Python"><span class="tocnumber">1.3</span> <span class="toctext">Ambienti di lavoro in Python</span></a></li>
<li class="toclevel-2 tocsection-5"><a href="#Workbench_in_C.2B.2B"><span class="tocnumber">1.4</span> <span class="toctext">Workbench in C++</span></a></li>
</ul>
</li>
<li class="toclevel-1 tocsection-6"><a href="#I_comandi_di_FreeCAD"><span class="tocnumber">2</span> <span class="toctext">I comandi di FreeCAD</span></a>
<ul>
<li class="toclevel-2 tocsection-7"><a href="#Definizione_dei_comandi_Python"><span class="tocnumber">2.1</span> <span class="toctext">Definizione dei comandi Python</span></a></li>
<li class="toclevel-2 tocsection-8"><a href="#Definizione_dei_comandi_C.2B.2B"><span class="tocnumber">2.2</span> <span class="toctext">Definizione dei comandi C++</span></a></li>
</ul>
</li>
</ul>
</div>
<h2><span class="mw-headline" id="La_struttura_del_workbench">La struttura del workbench</span></h2>
<p>Fondamentalmente è semplice: serve una cartella, con un nome a piacere, inserita nella directory Mod, contenente un file <i>Init.py</i> e, facoltativamente, un file <i>InitGui.py</i>. 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.
</p><p>All'interno questi file si può fare quello che si vuole. Di solito vengono utilizzati in questo modo:
</p>
<ul><li> 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</li></ul>
<ul><li> 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).</li></ul>
<h3><span class="mw-headline" id="Struttura_del_workbench_in_C.2B.2B">Struttura del workbench in C++</span></h3>
<p>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:
</p>
<pre>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&amp; 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();
}
} </pre>
<h3><span class="mw-headline" id="Il_file_Init.py">Il file Init.py</span></h3>
<pre># FreeCAD init script of XXX module
#***************************************************************************
#* (c) John Doe john@doe.com 2015 *
#* *
#* 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 LICENCE 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)","importOwn")
print "I am executing some stuff here when FreeCAD starts!" </pre>
<p>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 <a href="https://www.freecadweb.org/wiki/index.php?title=Code_snippets/it" title="Code snippets/it">esempi di codice</a>.
</p>
<h3><span class="mw-headline" id="Ambienti_di_lavoro_in_Python">Ambienti di lavoro in Python</span></h3>
<div class="mw-highlight mw-content-ltr" dir="ltr"><pre>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 FreeCAD starts"
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 when the workbench is activated"
return
def Deactivated(self):
"This function is executed when the workbench is deactivated"
return
def ContextMenu(self, recipient):
"This 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
return "Gui::PythonWorkbench"
Gui.addWorkbench(MyWorkbench())</pre></div>
<p>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.
</p>
<h3><span class="mw-headline" id="Workbench_in_C.2B.2B">Workbench in C++</span></h3>
<p>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:
</p>
<pre>import MyModuleGui </pre>
<p>dove MyModule è l'ambiente completo in C++, inclusi i comandi e la definizione dell'ambiente.
</p><p>La codificazione dei workbenches in C++ funziona in modo molto simile. Questo è un tipico file Workbench.cpp da includere nella parte Gui del modulo:
</p>
<pre>namespace MyModuleGui {
class MyModuleGuiExport Workbench&#160;: public Gui::StdWorkbench
{
TYPESYSTEM_HEADER();
public:
Workbench();
virtual ~Workbench();
virtual void activated();
virtual void deactivated();
protected:
Gui::ToolBarItem* setupToolBars() const;
Gui::MenuItem* setupMenuBar() const;
};
} </pre>
<h2><span class="mw-headline" id="I_comandi_di_FreeCAD">I comandi di FreeCAD</span></h2>
<p>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.
</p>
<h3><span class="mw-headline" id="Definizione_dei_comandi_Python">Definizione dei comandi Python</span></h3>
<pre>class My_Command_Class():
"""My new command"""
def GetResources(self):
return {'Pixmap' &#160;: 'My_Command_Icon', # the name of a svg file available in the resources
'Accel'&#160;: "Shift+S", # a default shortcut (optional)
'MenuText': "My New Command"
'ToolTip'&#160;: "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()) </pre>
<h3><span class="mw-headline" id="Definizione_dei_comandi_C.2B.2B">Definizione dei comandi C++</span></h3>
<p>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:
</p>
<pre>DEF_STD_CMD_A(CmdMyCommand);
CmdMyCommand::CmdMyCommand()
&#160;: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 &amp;rcCmdMgr = Gui::Application::Instance-&gt;commandManager();
rcCmdMgr.addCommand(new CmdMyCommand());
} </pre>
<p><br />
</p>
</div>
</div>
</div><div class="printfooter">
Online version: "<a dir="ltr" href="https://www.freecadweb.org/wiki/index.php?title=Workbench_creation/it&amp;oldid=189376">http://www.freecadweb.org/wiki/index.php?title=Workbench_creation/it&amp;oldid=189376</a>"</div>
<div id="catlinks" class="catlinks" data-mw="interface"></div><div class="visualClear"></div>
</div>
</div>
<div id="mw-navigation">
<h2>Navigation menu</h2>
</body></html>