Frammenti di codice

From FreeCAD Documentation
Revision as of 20:42, 24 May 2012 by Renatorivo (talk | contribs) (Created page with 'traduzione provvisoria (renatorivo) =Modelli di codici= Questa pagina contiene esempi, pezzi, parti in codice Python di FreeCAD raccolti dalle esperienze degli utenti e dalle d…')
(diff) ← Older revision | Latest revision (diff) | Newer revision → (diff)

traduzione provvisoria (renatorivo)

Modelli di codici

Questa pagina contiene esempi, pezzi, parti in codice Python di FreeCAD raccolti dalle esperienze degli utenti e dalle discussioni sui forum. Leggili e usali per iniziare a creare tuoi script personali ...

_

_


Un tipico file InitGui.py

Ogni modulo deve contenere, oltre al tuo file del modulo principale, un file InitGui.py, che ha la responsabilità di inserire il modulo nella finestra grafica principale (GUI).

Questo è un esempio di un semplice file InitGui.py:

class ScriptWorkbench (Workbench): 
    MenuText = "Scripts"
    def Initialize(self):
        import Scripts # assumendo che Scripts.py è il tuo modulo
        list = ["Script_Cmd"] # Tale elenco deve contenere i nomi dei comandi, che possono essere definiti in Scripts.py
        self.appendToolbar("My Scripts",list) 
        
Gui.addWorkbench(ScriptWorkbench())

Un tipico file del modulo

Il seguente è un esempio di un file del modulo principale, che contiene tutto ciò che fa il modulo. È il file Scripts.py richiamato dall'esempio precedente. In esso puoi avere (inserire) tutti i tuoi comandi personalizzati.


import FreeCAD, FreeCADGui 

class ScriptCmd: 
   def Activated(self): 
       # Here your write what your ScriptCmd does...
       FreeCAD.Console.PrintMessage('Hello, World!')
   def GetResources(self): 
       return {'Pixmap' : 'path_to_an_icon/myicon.png', 'MenuText': 'Short text', 'ToolTip': 'More detailed text'} 
      
FreeCADGui.addCommand('Script_Cmd', ScriptCmd())

Importare un nuovo tipo di file

In FreeCAD, è facile creare un importatore per un nuovo tipo di file. FreeCAD non considera che si importano dati in un documento aperto, ma piuttosto che semplicemente si può aprire direttamente il nuovo tipo di file. Quindi, quello che si deve fare è aggiungere la nuova estensione di file alla lista delle estensioni conosciute di FreeCAD, scrivere il codice che legge il file e creare gli oggetti di FreeCAD che si desidera:

Questa riga deve essere aggiunta al file InitGui.py per aggiungere la nuova estensione di file all'elenco:

# Si assume che Import_Ext.py è il file che contiene il codice per aprire e leggere i file .ext
FreeCAD.addImportType("Your new File Type (*.ext)","Import_Ext") 

Poi nel file Import_Ext.py:

def open(filename): 
   doc=App.newDocument()
   # qui si fa tutto ciò che serve fare con filename, leggere, classificare i dati, creare i corrispondenti oggetti FreeCAD
   doc.recompute()

L'esportazione di un proprio documento in un nuovo tipo di file funziona allo stesso modo, tranne che si utilizza:

FreeCAD.addExportType("Your new File Type (*.ext)","Export_Ext") 

Aggiungere una linea

Una linea ha semplicemente 2 punti.

import Part,PartGui 
doc=App.activeDocument() 
# aggiungere un elemento linea al documento e impostare i suoi punti 
l=Part.Line()
l.StartPoint=(0.0,0.0,0.0)
l.EndPoint=(1.0,1.0,1.0)
doc.addObject("Part::Feature","Line").Shape=l.toShape() 
doc.recompute()

Aggiungere un poligono

Un poligono è semplicemente un insieme di segmenti di linea collegati tra di loro (una polilinea in AutoCAD). Non è necessario che sia chiusa.

import Part,PartGui 
doc=App.activeDocument()
n=list() 
# creare un vettore 3D, impostare le sue coordinate e aggiungerlo alla lista
v=App.Vector(0,0,0) 
n.append(v) 
v=App.Vector(10,0,0) 
n.append(v) 
#... ripetere per tutti i nodi 
# Creare un oggetto poligono e impostate i suoi nodi 
p=doc.addObject("Part::Polygon","Polygon") 
p.Nodes=n 
doc.recompute()

Aggiungere e rimuovere un oggetto in un gruppo

doc=App.activeDocument() 
grp=doc.addObject("App::DocumentObjectGroup", "Group") 
lin=doc.addObject("Part::Feature", "Line")
grp.addObject(lin) # aggiunge l'oggetto lin al gruppo grp
grp.removeObject(lin) # rimuove l'oggetto lin dal gruppo grp

Nota: È anche possibile aggiungere dei gruppi a altri gruppi ...

Aggiungere un Mesh

import Mesh
doc=App.activeDocument()
# create a new empty mesh
m = Mesh.Mesh()
# build up box out of 12 facets
m.addFacet(0.0,0.0,0.0, 0.0,0.0,1.0, 0.0,1.0,1.0)
m.addFacet(0.0,0.0,0.0, 0.0,1.0,1.0, 0.0,1.0,0.0)
m.addFacet(0.0,0.0,0.0, 1.0,0.0,0.0, 1.0,0.0,1.0)
m.addFacet(0.0,0.0,0.0, 1.0,0.0,1.0, 0.0,0.0,1.0)
m.addFacet(0.0,0.0,0.0, 0.0,1.0,0.0, 1.0,1.0,0.0)
m.addFacet(0.0,0.0,0.0, 1.0,1.0,0.0, 1.0,0.0,0.0)
m.addFacet(0.0,1.0,0.0, 0.0,1.0,1.0, 1.0,1.0,1.0)
m.addFacet(0.0,1.0,0.0, 1.0,1.0,1.0, 1.0,1.0,0.0)
m.addFacet(0.0,1.0,1.0, 0.0,0.0,1.0, 1.0,0.0,1.0)
m.addFacet(0.0,1.0,1.0, 1.0,0.0,1.0, 1.0,1.0,1.0)
m.addFacet(1.0,1.0,0.0, 1.0,1.0,1.0, 1.0,0.0,1.0)
m.addFacet(1.0,1.0,0.0, 1.0,0.0,1.0, 1.0,0.0,0.0)
# scale to a edge langth of 100
m.scale(100.0)
# add the mesh to the active document
me=doc.addObject("Mesh::Feature","Cube")
me.Mesh=m

Aggiungere un arco o un cerchio

import Part
doc = App.activeDocument()
c = Part.Circle() 
c.Radius=10.0  
f = doc.addObject("Part::Feature", "Circle") # create a document with a circle feature 
f.Shape = c.toShape() # Assign the circle shape to the shape property 
doc.recompute()

Accedere alla rappresentazione di un oggetto e modificarla

Ogni oggetto di un documento di FreeCAD ha un oggetto di rappresentazione della vista a lui associato che memorizza tutti i parametri che definiscono il modo in cui l'oggetto stesso appare, come il colore, la larghezza di linea, ecc ..

gad=Gui.activeDocument()   # access the active document containing all 
                          # view representations of the features in the
                          # corresponding App document 

v=gad.getObject("Cube")    # access the view representation to the Mesh feature 'Cube' 
v.ShapeColor               # prints the color to the console 
v.ShapeColor=(1.0,1.0,1.0) # sets the shape color to white

Controllare gli eventi del mouse nel visualizzatore 3D tramite Python

La struttura di Inventor permette di aggiungere uno o più nodi di richiamo (callback) al grafico di scena (Scenegraph) della vista. In FreeCAD è installato di default un nodo callback per la vista che permette di aggiungere funzioni C++ globali o statiche. In appropriate associazioni Python vengono forniti alcuni metodi per utilizzare questa tecnica all'interno del codice Python.

App.newDocument()
v=Gui.activeDocument().activeView()

#This class logs any mouse button events. As the registered callback function fires twice for 'down' and
#'up' events we need a boolean flag to handle this.
class ViewObserver:
   def logPosition(self, info):
       down = (info["State"] == "DOWN")
       pos = info["Position"]
       if (down):
           FreeCAD.Console.PrintMessage("Clicked on position: ("+str(pos[0])+", "+str(pos[1])+")\n")
      
o = ViewObserver()
c = v.addEventCallback("SoMouseButtonEvent",o.logPosition)

Ora, cliccate in qualche parte nella zona nella vista 3D e osservate i messaggi nella finestra di output. Per terminare l'osservazione basta chiamare:

v.removeEventCallback("SoMouseButtonEvent",c)

Sono supportati i seguenti tipi di eventi:

  • SoEvent -- Tutti i tipi di eventi
  • SoButtonEvent -- Tutti gli eventi del mouse e della tastiera
  • SoLocation2Event -- Eventi di movimento 2D (normalmente i movimenti del mouse)
  • SoMotion3Event -- Eventi di movimento 3D (normalmente di spaceball)
  • SoKeyboradEvent -- Eventi dei tasti alto e basso
  • SoMouseButtonEvent -- Eventi dei pulsanti del mouse verso il basso e verso l'alto
  • SoSpaceballButtonEvent -- Eventi di SpaceBall in basso e in alto

La funzione di Python che può essere registrata con addEventCallback() si aspetta una difinizione. Secondo l'evento controllato la difinizione può contenere chiavi differenti.

Per tutti gli eventi esistono le seguenti chiavi:

  • Type -- Il nome del tipo di evento, ad esempio SoMouseEvent, SoLocation2Event, ...
  • Time -- L'ora corrente come stringa
  • Position -- Una tupla di due interi, dipendenti dalla posizione del mouse
  • ShiftDown -- un valore booleano, vero (true) se Shift è stato premuto altrimenti false
  • CtrlDown -- un valore booleano, true se è stato premuto Ctrl altrimenti false
  • AltDown -- un valore booleano, true se è stato premuto Alt altrimenti false

Per tutti gli eventi dei pulsanti, ad esempio eventi di tastiera, mouse o spaceball:

  • State -- Una stringa 'UP' se il pulsante è verso l'alto, 'DOWN' se è verso il basso o 'UNKNOWN' per tutti gli altri casi

Per gli eventi da tastiera:

  • Key -- Un carattere del tasto premuto

Per gli eventi del pulsante del mouse

  • Button -- Il pulsante premuto, potrebbe essere BUTTON1, ..., BUTTON5 o ANY

Per gli eventi di Spaceball:

  • Button -- Il pulsante premuto, potrebbe essere BUTTON1, ..., BUTTON7 o ANY

E infine eventi di movimento:

  • Translation -- Una tupla di tre numeri in virgola mobile
  • Rotation -- Un quaternione per la rotazione, cioè una tupla di quattro numeri in virgola mobile

Manipolare il grafo della scena in Python

E' anche possibile ottenere il Scenegraph (grafo della scena) in Python e modificarlo, con il modulo 'Pivy '- una associazione di Python per Coin.

from pivy.coin import *                # load the pivy module
view = Gui.ActiveDocument.ActiveView   # get the active viewer
root = view.getSceneGraph()            # the root is an SoSeparator node
root.addChild(SoCube())
view.fitAll()

L'API in Python di Pivy viene creato utilizzando lo strumento SWIG. In FreeCAD si usano alcuni nodi auto-scritti che non è possibile creare direttamente in Python. Tuttavia, è possibile creare un nodo dal suo nome interno.

Si può creare una istanza di tipo 'SoFCSelection' con:

type = SoType.fromName("SoFCSelection")
node = type.createInstance()

Aggiunta e rimozione di oggetti da e per il grafo della scena

L'aggiunta di nuovi nodi al Scenegraph può essere fatto in questo modo. Accertarsi di aggiungere sempre un SoSeparator per contenere la geometria, le coordinate e le informazioni sui materiale di uno stesso oggetto.

L'esempio seguente aggiunge una linea rossa da (0,0,0) a (10,0,0):

from pivy import coin
sg = Gui.ActiveDocument.ActiveView.getSceneGraph()
co = coin.SoCoordinate3()
pts = [[0,0,0],[10,0,0]]
co.point.setValues(0,len(pts),pts)
ma = coin.SoBaseColor()
ma.rgb = (1,0,0)
li = coin.SoLineSet()
li.numVertices.setValue(2)
no = coin.SoSeparator()
no.addChild(co)
no.addChild(ma)
no.addChild(li)
sg.addChild(no)

Per rimuoverla, è sufficiente scrivere:

sg.removeChild(no)

Aggiungere widget personalizzati all'interfaccia

È possibile creare widget personalizzati con Qt designer, trasformarli in uno script Python, e poi caricarli nell'interfaccia di FreeCAD con PyQt4.

Il codice Python prodotto dal compilatore Ui di Python (lo strumento che converte i file .ui di Qt-designer nel codice Python) appare in genere come questo (è semplice, si può anche codificare direttamente in Python):

class myWidget_Ui(object):
 def setupUi(self, myWidget):
   myWidget.setObjectName("my Nice New Widget")
   myWidget.resize(QtCore.QSize(QtCore.QRect(0,0,300,100).size()).expandedTo(myWidget.minimumSizeHint())) # sets size of the widget

   self.label = QtGui.QLabel(myWidget) # creates a label
   self.label.setGeometry(QtCore.QRect(50,50,200,24)) # sets its size
   self.label.setObjectName("label") # sets its name, so it can be found by name

 def retranslateUi(self, draftToolbar): # built-in QT function that manages translations of widgets
   myWidget.setWindowTitle(QtGui.QApplication.translate("myWidget", "My Widget", None, QtGui.QApplication.UnicodeUTF8))
   self.label.setText(QtGui.QApplication.translate("myWidget", "Welcome to my new widget!", None, QtGui.QApplication.UnicodeUTF8))				

Poi, tutto quello che serve è creare un riferimento alla finestra Qt di FreeCAD, inserire un widget personalizzato in essa, e "trasformare" questo widget nel proprio con il codice Ui che abbiamo appena creato:

 app = QtGui.qApp
 FCmw = app.activeWindow() # the active qt window, = the freecad window since we are inside it
 myNewFreeCADWidget = QtGui.QDockWidget() # create a new dckwidget
 myNewFreeCADWidget.ui = myWidget_Ui() # load the Ui script
 myNewFreeCADWidget.ui.setupUi(myNewFreeCADWidget) # setup the ui
 FCmw.addDockWidget(QtCore.Qt.RightDockWidgetArea,myNewFreeCADWidget) # add the widget to the main window

Aggiungere una scheda alla Combo View

Il codice seguente consente di aggiungere una scheda alla ComboView (vista combinata) di FreeCAD, oltre alle schede standard "Progetto" e "Attività". Esso utilizza anche il modulo UIC per caricare un file ui direttamente in questa nuova scheda.

from PyQt4 import QtGui,QtCore
from PyQt4 import uic
#from PySide import QtGui,QtCore

def getMainWindow():
   "returns the main window"
   # using QtGui.qApp.activeWindow() isn't very reliable because if another
   # widget than the mainwindow is active (e.g. a dialog) the wrong widget is
   # returned
   toplevel = QtGui.qApp.topLevelWidgets()
   for i in toplevel:
       if i.metaObject().className() == "Gui::MainWindow":
           return i
   raise Exception("No main window found")

def getComboView(mw):
   dw=mw.findChildren(QtGui.QDockWidget)
   for i in dw:
       if str(i.objectName()) == "Combo View":
           return i.findChild(QtGui.QTabWidget)
   raise Exception("No tab widget found")

mw = getMainWindow()
tab = getComboView(getMainWindow())
tab2=QtGui.QDialog()
tab.addTab(tab2,"A Special Tab")
uic.loadUi("/myTaskPanelforTabs.ui",tab2)
tab2.show()

#tab.removeTab(2)

Aprire una specifica pagina Web

import WebGui
WebGui.openBrowser("http://www.example.com")

Ottenere il contenuto HTML di una pagina web aperta

from PyQt4 import QtGui,QtWebKit
a = QtGui.qApp
mw = a.activeWindow()
v = mw.findChild(QtWebKit.QWebFrame)
html = unicode(v.toHtml())
print html
Altre lingue: Template:Se