├── .gitignore ├── License.md ├── basic1_wb ├── Basic1Gui.py ├── Init.py ├── InitGui.py └── icons │ └── basic1_makebox_cmd.svg ├── basic2_wb ├── Basic2Gui.py ├── Init.py ├── InitGui.py └── icons │ ├── basic2_makebox_cmd.svg │ └── basic2_makeboxdialog_cmd.svg ├── basic3_wb ├── Basic3Gui.py ├── Init.py ├── InitGui.py └── icons │ ├── basic3_makebox_cmd.svg │ ├── basic3_makeboxdialog_cmd.svg │ └── basic3_makeboxedge_cmd.svg ├── basic4_wb ├── Basic4Gui.py ├── Init.py ├── InitGui.py └── icons │ ├── basic4_makebox_cmd.svg │ ├── basic4_makeboxdialog_cmd.svg │ ├── basic4_makeboxedge_cmd.svg │ └── basic4_makeboxparam_cmd.svg ├── imgs ├── b1_wb.svg ├── b1_wb.xcf ├── b1_wb.xpm ├── b2_wb.xcf ├── b2_wb.xpm ├── b2_wb_flat.xcf ├── b3_wb.xcf ├── b3_wb.xpm ├── b3_wb_flat.xcf ├── b4_wb.xcf ├── b4_wb.xpm ├── b4_wb_flat.xcf ├── wb2_dialog.png ├── wb2_toolbar.png ├── wb3_dialog.png ├── wb3_toolbar.png ├── wb4_dialog.png ├── wb_active.png ├── wb_active_name.png ├── wb_icon_sel.png ├── wb_icon_sel_name.png ├── wb_no_file.png ├── wb_no_file_name.png └── wb_selection.png ├── readme.md ├── tut_fwb_1.md ├── tut_fwb_2.md ├── tut_fwb_3.md └── tut_fwb_4.md /.gitignore: -------------------------------------------------------------------------------- 1 | # vi temporary files: 2 | *~ 3 | *.swp 4 | .* 5 | 6 | # freecad 7 | *.FCStd1 8 | 9 | # python 10 | *.pyc 11 | 12 | # old directory 13 | old/ 14 | -------------------------------------------------------------------------------- /License.md: -------------------------------------------------------------------------------- 1 | GNU LESSER GENERAL PUBLIC LICENSE 2 | Version 3, 29 June 2007 3 | 4 | Copyright (C) 2007 Free Software Foundation, Inc. 5 | Everyone is permitted to copy and distribute verbatim copies 6 | of this license document, but changing it is not allowed. 7 | 8 | 9 | This version of the GNU Lesser General Public License incorporates 10 | the terms and conditions of version 3 of the GNU General Public 11 | License, supplemented by the additional permissions listed below. 12 | 13 | 0. Additional Definitions. 14 | 15 | As used herein, "this License" refers to version 3 of the GNU Lesser 16 | General Public License, and the "GNU GPL" refers to version 3 of the GNU 17 | General Public License. 18 | 19 | "The Library" refers to a covered work governed by this License, 20 | other than an Application or a Combined Work as defined below. 21 | 22 | An "Application" is any work that makes use of an interface provided 23 | by the Library, but which is not otherwise based on the Library. 24 | Defining a subclass of a class defined by the Library is deemed a mode 25 | of using an interface provided by the Library. 26 | 27 | A "Combined Work" is a work produced by combining or linking an 28 | Application with the Library. The particular version of the Library 29 | with which the Combined Work was made is also called the "Linked 30 | Version". 31 | 32 | The "Minimal Corresponding Source" for a Combined Work means the 33 | Corresponding Source for the Combined Work, excluding any source code 34 | for portions of the Combined Work that, considered in isolation, are 35 | based on the Application, and not on the Linked Version. 36 | 37 | The "Corresponding Application Code" for a Combined Work means the 38 | object code and/or source code for the Application, including any data 39 | and utility programs needed for reproducing the Combined Work from the 40 | Application, but excluding the System Libraries of the Combined Work. 41 | 42 | 1. Exception to Section 3 of the GNU GPL. 43 | 44 | You may convey a covered work under sections 3 and 4 of this License 45 | without being bound by section 3 of the GNU GPL. 46 | 47 | 2. Conveying Modified Versions. 48 | 49 | If you modify a copy of the Library, and, in your modifications, a 50 | facility refers to a function or data to be supplied by an Application 51 | that uses the facility (other than as an argument passed when the 52 | facility is invoked), then you may convey a copy of the modified 53 | version: 54 | 55 | a) under this License, provided that you make a good faith effort to 56 | ensure that, in the event an Application does not supply the 57 | function or data, the facility still operates, and performs 58 | whatever part of its purpose remains meaningful, or 59 | 60 | b) under the GNU GPL, with none of the additional permissions of 61 | this License applicable to that copy. 62 | 63 | 3. Object Code Incorporating Material from Library Header Files. 64 | 65 | The object code form of an Application may incorporate material from 66 | a header file that is part of the Library. You may convey such object 67 | code under terms of your choice, provided that, if the incorporated 68 | material is not limited to numerical parameters, data structure 69 | layouts and accessors, or small macros, inline functions and templates 70 | (ten or fewer lines in length), you do both of the following: 71 | 72 | a) Give prominent notice with each copy of the object code that the 73 | Library is used in it and that the Library and its use are 74 | covered by this License. 75 | 76 | b) Accompany the object code with a copy of the GNU GPL and this license 77 | document. 78 | 79 | 4. Combined Works. 80 | 81 | You may convey a Combined Work under terms of your choice that, 82 | taken together, effectively do not restrict modification of the 83 | portions of the Library contained in the Combined Work and reverse 84 | engineering for debugging such modifications, if you also do each of 85 | the following: 86 | 87 | a) Give prominent notice with each copy of the Combined Work that 88 | the Library is used in it and that the Library and its use are 89 | covered by this License. 90 | 91 | b) Accompany the Combined Work with a copy of the GNU GPL and this license 92 | document. 93 | 94 | c) For a Combined Work that displays copyright notices during 95 | execution, include the copyright notice for the Library among 96 | these notices, as well as a reference directing the user to the 97 | copies of the GNU GPL and this license document. 98 | 99 | d) Do one of the following: 100 | 101 | 0) Convey the Minimal Corresponding Source under the terms of this 102 | License, and the Corresponding Application Code in a form 103 | suitable for, and under terms that permit, the user to 104 | recombine or relink the Application with a modified version of 105 | the Linked Version to produce a modified Combined Work, in the 106 | manner specified by section 6 of the GNU GPL for conveying 107 | Corresponding Source. 108 | 109 | 1) Use a suitable shared library mechanism for linking with the 110 | Library. A suitable mechanism is one that (a) uses at run time 111 | a copy of the Library already present on the user's computer 112 | system, and (b) will operate properly with a modified version 113 | of the Library that is interface-compatible with the Linked 114 | Version. 115 | 116 | e) Provide Installation Information, but only if you would otherwise 117 | be required to provide such information under section 6 of the 118 | GNU GPL, and only to the extent that such information is 119 | necessary to install and execute a modified version of the 120 | Combined Work produced by recombining or relinking the 121 | Application with a modified version of the Linked Version. (If 122 | you use option 4d0, the Installation Information must accompany 123 | the Minimal Corresponding Source and Corresponding Application 124 | Code. If you use option 4d1, you must provide the Installation 125 | Information in the manner specified by section 6 of the GNU GPL 126 | for conveying Corresponding Source.) 127 | 128 | 5. Combined Libraries. 129 | 130 | You may place library facilities that are a work based on the 131 | Library side by side in a single library together with other library 132 | facilities that are not Applications and are not covered by this 133 | License, and convey such a combined library under terms of your 134 | choice, if you do both of the following: 135 | 136 | a) Accompany the combined library with a copy of the same work based 137 | on the Library, uncombined with any other library facilities, 138 | conveyed under the terms of this License. 139 | 140 | b) Give prominent notice with the combined library that part of it 141 | is a work based on the Library, and explaining where to find the 142 | accompanying uncombined form of the same work. 143 | 144 | 6. Revised Versions of the GNU Lesser General Public License. 145 | 146 | The Free Software Foundation may publish revised and/or new versions 147 | of the GNU Lesser General Public License from time to time. Such new 148 | versions will be similar in spirit to the present version, but may 149 | differ in detail to address new problems or concerns. 150 | 151 | Each version is given a distinguishing version number. If the 152 | Library as you received it specifies that a certain numbered version 153 | of the GNU Lesser General Public License "or any later version" 154 | applies to it, you have the option of following the terms and 155 | conditions either of that published version or of any later version 156 | published by the Free Software Foundation. If the Library as you 157 | received it does not specify a version number of the GNU Lesser 158 | General Public License, you may choose any version of the GNU Lesser 159 | General Public License ever published by the Free Software Foundation. 160 | 161 | If the Library as you received it specifies that a proxy can decide 162 | whether future versions of the GNU Lesser General Public License shall 163 | apply, that proxy's public statement of acceptance of any version is 164 | permanent authorization for you to choose that version for the 165 | Library. 166 | -------------------------------------------------------------------------------- /basic1_wb/Basic1Gui.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | # FreeCAD script for the commands of the basic workbench creation tutorial 3 | # (c) 2017 Felipe Machado 4 | 5 | #*************************************************************************** 6 | #* (c) Felipe Machado https://github.com/felipe-m 2017 * 7 | #* * 8 | #* This file is part of the FreeCAD CAx development system. * 9 | #* * 10 | #* This program is free software; you can redistribute it and/or modify * 11 | #* it under the terms of the GNU Lesser General Public License (LGPL) * 12 | #* as published by the Free Software Foundation; either version 2 of * 13 | #* the License, or (at your option) any later version. * 14 | #* for detail see the LICENCE text file. * 15 | #* * 16 | #* FreeCAD is distributed in the hope that it will be useful, * 17 | #* but WITHOUT ANY WARRANTY; without even the implied warranty of * 18 | #* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * 19 | #* GNU Lesser General Public License for more details. * 20 | #* * 21 | #* You should have received a copy of the GNU Library General Public * 22 | #* License along with FreeCAD; if not, write to the Free Software * 23 | #* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 * 24 | #* USA * 25 | #* * 26 | #***************************************************************************/ 27 | 28 | import PySide 29 | from PySide import QtCore, QtGui 30 | import FreeCAD 31 | import FreeCADGui 32 | import Part 33 | import os 34 | 35 | __dir__ = os.path.dirname(__file__) 36 | 37 | # FreeCAD Command made with a Python script 38 | def MakeBox(): 39 | doc = FreeCAD.ActiveDocument 40 | box = doc.addObject("Part::Box",'box') 41 | box.Length = 1 42 | box.Width = 1 43 | box.Height = 1 44 | 45 | # GUI command that links the Python script 46 | class _MakeBoxCmd: 47 | """Command to create a box""" 48 | 49 | 50 | def Activated(self): 51 | # what is done when the command is clicked 52 | MakeBox() 53 | 54 | def GetResources(self): 55 | # icon and command information 56 | MenuText = QtCore.QT_TRANSLATE_NOOP( 57 | 'Basic1_Box', 58 | 'Box') 59 | ToolTip = QtCore.QT_TRANSLATE_NOOP( 60 | 'Basic1_Box', 61 | 'Creates a new box') 62 | return { 63 | 'Pixmap': __dir__ + '/icons/basic1_makebox_cmd.svg', 64 | 'MenuText': MenuText, 65 | 'ToolTip': ToolTip} 66 | 67 | def IsActive(self): 68 | # The command will be active if there is an active document 69 | return not FreeCAD.ActiveDocument is None 70 | 71 | FreeCADGui.addCommand('Basic1_MakeBox', _MakeBoxCmd()) 72 | -------------------------------------------------------------------------------- /basic1_wb/Init.py: -------------------------------------------------------------------------------- 1 | # FreeCAD init script of BASIC1_WB module 2 | 3 | #*************************************************************************** 4 | #* (c) Felipe Machado https://github.com/felipe-m 2017 * 5 | #* * 6 | #* This file is part of the FreeCAD CAx development system. * 7 | #* * 8 | #* This program is free software; you can redistribute it and/or modify * 9 | #* it under the terms of the GNU Lesser General Public License (LGPL) * 10 | #* as published by the Free Software Foundation; either version 2 of * 11 | #* the License, or (at your option) any later version. * 12 | #* for detail see the LICENCE text file. * 13 | #* * 14 | #* FreeCAD is distributed in the hope that it will be useful, * 15 | #* but WITHOUT ANY WARRANTY; without even the implied warranty of * 16 | #* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * 17 | #* GNU Lesser General Public License for more details. * 18 | #* * 19 | #* You should have received a copy of the GNU Library General Public * 20 | #* License along with FreeCAD; if not, write to the Free Software * 21 | #* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 * 22 | #* USA * 23 | #* * 24 | #***************************************************************************/ 25 | -------------------------------------------------------------------------------- /basic1_wb/InitGui.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | # FreeCAD init script of the Basic 1 module, 3 | # very simple workbench, just for the tutorial 4 | 5 | #*************************************************************************** 6 | #* (c) Felipe Machado https://github.com/felipe-m 2017 * 7 | #* * 8 | #* This file is part of the FreeCAD CAx development system. * 9 | #* * 10 | #* This program is free software; you can redistribute it and/or modify * 11 | #* it under the terms of the GNU Lesser General Public License (LGPL) * 12 | #* as published by the Free Software Foundation; either version 2 of * 13 | #* the License, or (at your option) any later version. * 14 | #* for detail see the LICENCE text file. * 15 | #* * 16 | #* FreeCAD is distributed in the hope that it will be useful, * 17 | #* but WITHOUT ANY WARRANTY; without even the implied warranty of * 18 | #* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * 19 | #* GNU Lesser General Public License for more details. * 20 | #* * 21 | #* You should have received a copy of the GNU Library General Public * 22 | #* License along with FreeCAD; if not, write to the Free Software * 23 | #* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 * 24 | #* USA * 25 | #* * 26 | #***************************************************************************/ 27 | 28 | 29 | class Basic1Workbench (Workbench): 30 | """Basic 1 workbench object""" 31 | # this is the icon in XPM format 16x16 pixels 32 | Icon = """ 33 | /* XPM */ 34 | static char * basic1_xpm[] = { 35 | "16 16 5 1", 36 | " c None", 37 | ". c #FFFFFF", 38 | "+ c #000000", 39 | "@ c #7F4F00", 40 | "# c #FFBF00", 41 | "................", 42 | "...++++++++++++.", 43 | "..+@#########++.", 44 | ".+@#########+@+.", 45 | ".+++++++++++@#+.", 46 | ".+#########+##+.", 47 | ".+###++####+##+.", 48 | ".+####+####+##+.", 49 | ".+####+####+##+.", 50 | ".+####+####+##+.", 51 | ".+####+####+##+.", 52 | ".+####+####+##+.", 53 | ".+###+++###+#@+.", 54 | ".+#########+@+..", 55 | ".++++++++++++...", 56 | "................"}; 57 | """ 58 | 59 | MenuText = "Basic1" 60 | ToolTip = "Basic 1 workbench" 61 | 62 | def Initialize(self) : 63 | "This function is executed when FreeCAD starts" 64 | from PySide import QtCore, QtGui 65 | # python file where the commands are: 66 | import Basic1Gui 67 | # list of commands, only one (it is in the imported Basic1Gui): 68 | cmdlist = [ "Basic1_MakeBox"] 69 | self.appendToolbar( 70 | str(QtCore.QT_TRANSLATE_NOOP("Basic1", "Basic1")), cmdlist) 71 | self.appendMenu( 72 | str(QtCore.QT_TRANSLATE_NOOP("Basic1", "Basic1")), cmdlist) 73 | 74 | Log ('Loading Basic1 module... done\n') 75 | 76 | def GetClassName(self): 77 | return "Gui::PythonWorkbench" 78 | 79 | # The workbench is added 80 | Gui.addWorkbench(Basic1Workbench()) 81 | 82 | -------------------------------------------------------------------------------- /basic1_wb/icons/basic1_makebox_cmd.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 19 | 21 | 40 | 42 | 43 | 45 | image/svg+xml 46 | 48 | 49 | 50 | 51 | 52 | 57 | 64 | 69 | 75 | 76 | 77 | -------------------------------------------------------------------------------- /basic2_wb/Basic2Gui.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | # FreeCAD script for the commands of the basic workbench creation tutorial 3 | # (c) 2017 Felipe Machado 4 | 5 | #*************************************************************************** 6 | #* (c) Felipe Machado https://github.com/felipe-m 2017 * 7 | #* * 8 | #* This file is part of the FreeCAD CAx development system. * 9 | #* * 10 | #* This program is free software; you can redistribute it and/or modify * 11 | #* it under the terms of the GNU Lesser General Public License (LGPL) * 12 | #* as published by the Free Software Foundation; either version 2 of * 13 | #* the License, or (at your option) any later version. * 14 | #* for detail see the LICENCE text file. * 15 | #* * 16 | #* FreeCAD is distributed in the hope that it will be useful, * 17 | #* but WITHOUT ANY WARRANTY; without even the implied warranty of * 18 | #* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * 19 | #* GNU Lesser General Public License for more details. * 20 | #* * 21 | #* You should have received a copy of the GNU Library General Public * 22 | #* License along with FreeCAD; if not, write to the Free Software * 23 | #* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 * 24 | #* USA * 25 | #* * 26 | #***************************************************************************/ 27 | 28 | import PySide 29 | from PySide import QtCore, QtGui 30 | import FreeCAD 31 | import FreeCADGui 32 | import Part 33 | import os 34 | 35 | from DraftTools import translate 36 | 37 | __dir__ = os.path.dirname(__file__) 38 | 39 | # FreeCAD Command made with a Python script 40 | def MakeBox(): 41 | doc = FreeCAD.ActiveDocument 42 | box = doc.addObject("Part::Box",'box') 43 | box.Length = 1 44 | box.Width = 1 45 | box.Height = 1 46 | 47 | # GUI command that links the Python script 48 | class _MakeBoxCmd: 49 | """Command to create a box""" 50 | 51 | def Activated(self): 52 | # what is done when the command is clicked 53 | MakeBox() 54 | 55 | def GetResources(self): 56 | # icon and command information 57 | MenuText = QtCore.QT_TRANSLATE_NOOP( 58 | 'Basic2_Box', 59 | 'Box 1 1 1') 60 | ToolTip = QtCore.QT_TRANSLATE_NOOP( 61 | 'Basic2_Box', 62 | 'Creates a new box') 63 | return { 64 | 'Pixmap': __dir__ + '/icons/basic2_makebox_cmd.svg', 65 | 'MenuText': MenuText, 66 | 'ToolTip': ToolTip} 67 | 68 | def IsActive(self): 69 | # The command will be active if there is an active document 70 | return not FreeCAD.ActiveDocument is None 71 | 72 | # ---------- classes to make a box with a dialog 73 | 74 | # Task Panel creation: the task panel has to have: 75 | # 1. a widget called self.form 76 | # 2. reject and accept methods (if needed) 77 | class BoxSimpleTaskPanel: 78 | def __init__(self,widget): 79 | self.form = widget 80 | 81 | # Ok and Cancel buttons are created by default in FreeCAD Task Panels 82 | # What is done when we click on the ok button. 83 | def accept(self): 84 | MakeBox() 85 | FreeCADGui.Control.closeDialog() #close the dialog 86 | 87 | # What is done when we click on the cancel button. 88 | # commented because this is the default behaviour 89 | #def reject(self): 90 | # FreeCADGui.Control.closeDialog() 91 | 92 | # GUI command that links the Python script 93 | class _MakeBoxDialogCmd: 94 | """Command to create a box with a very simple dialog 95 | """ 96 | 97 | def Activated(self): 98 | # what is done when the command is clicked 99 | # creates a panel with a dialog 100 | baseWidget = QtGui.QWidget() 101 | panel = BoxSimpleTaskPanel(baseWidget) 102 | # having a panel with a widget in self.form and the accept and 103 | # reject functions (if needed), we can open it: 104 | FreeCADGui.Control.showDialog(panel) 105 | 106 | def GetResources(self): 107 | # icon and command information 108 | MenuText = QtCore.QT_TRANSLATE_NOOP( 109 | 'Basic2_DBox', 110 | 'Box Dialog') 111 | ToolTip = QtCore.QT_TRANSLATE_NOOP( 112 | 'Basic2_DBox', 113 | 'Creates a box using a task panel dialog') 114 | return { 115 | 'Pixmap': __dir__ + '/icons/basic2_makeboxdialog_cmd.svg', 116 | 'MenuText': MenuText, 117 | 'ToolTip': ToolTip} 118 | 119 | def IsActive(self): 120 | # The command will be active if there is an active document 121 | return not FreeCAD.ActiveDocument is None 122 | 123 | FreeCADGui.addCommand('Basic2_MakeBox', _MakeBoxCmd()) 124 | FreeCADGui.addCommand('Basic2_MakeBoxDialog', _MakeBoxDialogCmd()) 125 | -------------------------------------------------------------------------------- /basic2_wb/Init.py: -------------------------------------------------------------------------------- 1 | # FreeCAD init script of BASIC1_WB module 2 | 3 | #*************************************************************************** 4 | #* (c) Felipe Machado https://github.com/felipe-m 2017 * 5 | #* * 6 | #* This file is part of the FreeCAD CAx development system. * 7 | #* * 8 | #* This program is free software; you can redistribute it and/or modify * 9 | #* it under the terms of the GNU Lesser General Public License (LGPL) * 10 | #* as published by the Free Software Foundation; either version 2 of * 11 | #* the License, or (at your option) any later version. * 12 | #* for detail see the LICENCE text file. * 13 | #* * 14 | #* FreeCAD is distributed in the hope that it will be useful, * 15 | #* but WITHOUT ANY WARRANTY; without even the implied warranty of * 16 | #* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * 17 | #* GNU Lesser General Public License for more details. * 18 | #* * 19 | #* You should have received a copy of the GNU Library General Public * 20 | #* License along with FreeCAD; if not, write to the Free Software * 21 | #* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 * 22 | #* USA * 23 | #* * 24 | #***************************************************************************/ 25 | -------------------------------------------------------------------------------- /basic2_wb/InitGui.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | # FreeCAD init script of the Basic 2 module, 3 | # simple workbench, just for the tutorial 4 | 5 | #*************************************************************************** 6 | #* (c) Felipe Machado https://github.com/felipe-m 2017 * 7 | #* * 8 | #* This file is part of the FreeCAD CAx development system. * 9 | #* * 10 | #* This program is free software; you can redistribute it and/or modify * 11 | #* it under the terms of the GNU Lesser General Public License (LGPL) * 12 | #* as published by the Free Software Foundation; either version 2 of * 13 | #* the License, or (at your option) any later version. * 14 | #* for detail see the LICENCE text file. * 15 | #* * 16 | #* FreeCAD is distributed in the hope that it will be useful, * 17 | #* but WITHOUT ANY WARRANTY; without even the implied warranty of * 18 | #* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * 19 | #* GNU Lesser General Public License for more details. * 20 | #* * 21 | #* You should have received a copy of the GNU Library General Public * 22 | #* License along with FreeCAD; if not, write to the Free Software * 23 | #* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 * 24 | #* USA * 25 | #* * 26 | #***************************************************************************/ 27 | 28 | 29 | class Basic2Workbench (Workbench): 30 | """Basic 2 workbench object""" 31 | # this is the icon in XPM format 16x16 pixels 32 | Icon = """ 33 | /* XPM */ 34 | static char * basic2_xpm[] = { 35 | "16 16 8 1", 36 | " c None", 37 | ". c #FFFFFF", 38 | "+ c #000000", 39 | "@ c #6D5100", 40 | "# c #FFBF00", 41 | "$ c #B88900", 42 | "% c #E5AB00", 43 | "& c #FEBE00", 44 | "................", 45 | "...++++++++++++.", 46 | "..+@#########++.", 47 | ".+@#########+@+.", 48 | ".+++++++++++@#+.", 49 | ".+#########+##+.", 50 | ".+##$++$###+##+.", 51 | ".+##@%$+###+##+.", 52 | ".+####%+###+##+.", 53 | ".+###&+%###+##+.", 54 | ".+###+$####+##+.", 55 | ".+##+@#####+##+.", 56 | ".+##++++###+#@+.", 57 | ".+#########+@+..", 58 | ".++++++++++++...", 59 | "................"}; 60 | """ 61 | MenuText = "Basic2" 62 | ToolTip = "Basic 2 workbench" 63 | 64 | def Initialize(self) : 65 | "This function is executed when FreeCAD starts" 66 | from PySide import QtCore, QtGui 67 | # python file where the commands are: 68 | import Basic2Gui 69 | # list of commands, just 2 (they are in the imported Basic2Gui): 70 | cmdlist = [ "Basic2_MakeBox", "Basic2_MakeBoxDialog"] 71 | self.appendToolbar( 72 | str(QtCore.QT_TRANSLATE_NOOP("Basic2", "Basic2")), cmdlist) 73 | self.appendMenu( 74 | str(QtCore.QT_TRANSLATE_NOOP("Basic2", "Basic2")), cmdlist) 75 | 76 | Log ('Loading Basic2 module... done\n') 77 | 78 | def GetClassName(self): 79 | return "Gui::PythonWorkbench" 80 | 81 | # The workbench is added 82 | Gui.addWorkbench(Basic2Workbench()) 83 | 84 | -------------------------------------------------------------------------------- /basic2_wb/icons/basic2_makebox_cmd.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 19 | 21 | 40 | 42 | 43 | 45 | image/svg+xml 46 | 48 | 49 | 50 | 51 | 52 | 57 | 64 | 69 | 75 | 76 | 77 | -------------------------------------------------------------------------------- /basic2_wb/icons/basic2_makeboxdialog_cmd.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 19 | 21 | 40 | 42 | 43 | 45 | image/svg+xml 46 | 48 | 49 | 50 | 51 | 52 | 57 | 64 | 69 | 75 | d 86 | 87 | 88 | -------------------------------------------------------------------------------- /basic3_wb/Basic3Gui.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | # FreeCAD script for the commands of the basic workbench creation tutorial 3 | # (c) 2017 Felipe Machado 4 | 5 | #*************************************************************************** 6 | #* (c) Felipe Machado 2017 * 7 | #* https://github.com/felipe-m/tutorial_freecad_wb * 8 | #* * 9 | #* This file is part of the FreeCAD CAx development system. * 10 | #* * 11 | #* This program is free software; you can redistribute it and/or modify * 12 | #* it under the terms of the GNU Lesser General Public License (LGPL) * 13 | #* as published by the Free Software Foundation; either version 2 of * 14 | #* the License, or (at your option) any later version. * 15 | #* for detail see the LICENCE text file. * 16 | #* * 17 | #* FreeCAD is distributed in the hope that it will be useful, * 18 | #* but WITHOUT ANY WARRANTY; without even the implied warranty of * 19 | #* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * 20 | #* GNU Lesser General Public License for more details. * 21 | #* * 22 | #* You should have received a copy of the GNU Library General Public * 23 | #* License along with FreeCAD; if not, write to the Free Software * 24 | #* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 * 25 | #* USA * 26 | #* * 27 | #***************************************************************************/ 28 | 29 | import PySide 30 | from PySide import QtCore, QtGui 31 | import FreeCAD 32 | import FreeCADGui 33 | import Part 34 | import os 35 | 36 | __dir__ = os.path.dirname(__file__) 37 | 38 | # FreeCAD Command made with a Python script 39 | def MakeBox(edge_len = 1, boxname='box'): 40 | doc = FreeCAD.ActiveDocument 41 | box = doc.addObject("Part::Box",boxname) 42 | box.Length = edge_len 43 | box.Width = edge_len 44 | box.Height = edge_len 45 | 46 | # GUI command that links the Python script 47 | class _MakeBoxCmd: 48 | """Command to create a box""" 49 | 50 | def Activated(self): 51 | # what is done when the command is clicked 52 | MakeBox() 53 | 54 | def GetResources(self): 55 | # icon and command information 56 | MenuText = QtCore.QT_TRANSLATE_NOOP( 57 | 'Basic3_Box', 58 | 'Box 1 1 1') 59 | ToolTip = QtCore.QT_TRANSLATE_NOOP( 60 | 'Basic3_Box', 61 | 'Creates a new box') 62 | return { 63 | 'Pixmap': __dir__ + '/icons/basic3_makebox_cmd.svg', 64 | 'MenuText': MenuText, 65 | 'ToolTip': ToolTip} 66 | 67 | def IsActive(self): 68 | # The command will be active if there is an active document 69 | return not FreeCAD.ActiveDocument is None 70 | 71 | # ---------- classes to make a box with a dialog 72 | 73 | # Task Panel creation: the task panel has to have: 74 | # 1. a widget called self.form 75 | # 2. reject and accept methods (if needed) 76 | class BoxSimpleTaskPanel: 77 | def __init__(self,widget): 78 | self.form = widget 79 | 80 | # Ok and Cancel buttons are created by default in FreeCAD Task Panels 81 | # What is done when we click on the ok button. 82 | def accept(self): 83 | MakeBox(boxname='box_dialog') 84 | FreeCADGui.Control.closeDialog() #close the dialog 85 | 86 | # What is done when we click on the cancel button. 87 | # commented because this is the default behaviour 88 | #def reject(self): 89 | # FreeCADGui.Control.closeDialog() 90 | 91 | # GUI command that links the Python script 92 | class _MakeBoxDialogCmd: 93 | """Command to create a box with a very simple dialog 94 | """ 95 | 96 | def Activated(self): 97 | # what is done when the command is clicked 98 | # creates a panel with a dialog 99 | baseWidget = QtGui.QWidget() 100 | panel = BoxSimpleTaskPanel(baseWidget) 101 | # having a panel with a widget in self.form and the accept and 102 | # reject functions (if needed), we can open it: 103 | FreeCADGui.Control.showDialog(panel) 104 | 105 | def GetResources(self): 106 | # icon and command information 107 | MenuText = QtCore.QT_TRANSLATE_NOOP( 108 | 'Basic3_DBox', 109 | 'Box Dialog') 110 | ToolTip = QtCore.QT_TRANSLATE_NOOP( 111 | 'Basic3_DBox', 112 | 'Creates a box using a task panel dialog') 113 | return { 114 | 'Pixmap': __dir__ + '/icons/basic3_makeboxdialog_cmd.svg', 115 | 'MenuText': MenuText, 116 | 'ToolTip': ToolTip} 117 | 118 | def IsActive(self): 119 | # The command will be active if there is an active document 120 | return not FreeCAD.ActiveDocument is None 121 | 122 | 123 | # classes to make a box with a dialog where the Edge length can be set 124 | 125 | # Task Panel creation: the task panel has to have: 126 | # 1. a widget called self.form 127 | # 2. reject and accept methods (if needed) 128 | class BoxEdgePTaskPanel: 129 | def __init__(self,widget): 130 | self.form = widget 131 | # The layout will be horizontal 132 | layout = QtGui.QHBoxLayout() 133 | # Label: 134 | self.edgeLabel = QtGui.QLabel("Cube's edge length (mm)") 135 | # Spin Box that takes doubles 136 | self.edgeValue = QtGui.QDoubleSpinBox() 137 | # Default value 138 | self.edgeValue.setValue(1) 139 | # suffix to indicate the units 140 | self.edgeValue.setSuffix(' mm') 141 | layout.addWidget(self.edgeLabel) 142 | layout.addWidget(self.edgeValue) 143 | self.form.setLayout(layout) 144 | 145 | # Ok and Cancel buttons are created by default in FreeCAD Task Panels 146 | # What is done when we click on the ok button. 147 | def accept(self): 148 | edge_length = self.edgeValue.value() 149 | MakeBox(edge_length, 'box_edge') 150 | FreeCADGui.Control.closeDialog() #close the dialog 151 | 152 | # What is done when we click on the cancel button. 153 | # commented because this is the default behaviour 154 | #def reject(self): 155 | # FreeCADGui.Control.closeDialog() 156 | 157 | # GUI command that links the Python script 158 | class _MakeBoxEdgeP: 159 | """Command to create a box with a dialog where you can set the Edge length 160 | """ 161 | 162 | def Activated(self): 163 | # what is done when the command is clicked 164 | # creates a panel with a dialog 165 | baseWidget = QtGui.QWidget() 166 | panel = BoxEdgePTaskPanel(baseWidget) 167 | # having a panel with a widget in self.form and the accept and 168 | # reject functions (if needed), we can open it: 169 | FreeCADGui.Control.showDialog(panel) 170 | 171 | def GetResources(self): 172 | # icon and command information 173 | MenuText = QtCore.QT_TRANSLATE_NOOP( 174 | 'Basic3_EBox', 175 | 'Edge Parameter Box Dialog') 176 | ToolTip = QtCore.QT_TRANSLATE_NOOP( 177 | 'Basic3_EBox', 178 | 'Creates a box using a dialog to choose the edge length') 179 | return { 180 | 'Pixmap': __dir__ + '/icons/basic3_makeboxedge_cmd.svg', 181 | 'MenuText': MenuText, 182 | 'ToolTip': ToolTip} 183 | 184 | def IsActive(self): 185 | # The command will be active if there is an active document 186 | return not FreeCAD.ActiveDocument is None 187 | 188 | 189 | FreeCADGui.addCommand('Basic3_MakeBox', _MakeBoxCmd()) 190 | FreeCADGui.addCommand('Basic3_MakeBoxDialog', _MakeBoxDialogCmd()) 191 | FreeCADGui.addCommand('Basic3_MakeBoxEdgeP', _MakeBoxEdgeP()) 192 | -------------------------------------------------------------------------------- /basic3_wb/Init.py: -------------------------------------------------------------------------------- 1 | # FreeCAD init script of BASIC1_WB module 2 | 3 | #*************************************************************************** 4 | #* (c) Felipe Machado https://github.com/felipe-m 2017 * 5 | #* * 6 | #* This file is part of the FreeCAD CAx development system. * 7 | #* * 8 | #* This program is free software; you can redistribute it and/or modify * 9 | #* it under the terms of the GNU Lesser General Public License (LGPL) * 10 | #* as published by the Free Software Foundation; either version 2 of * 11 | #* the License, or (at your option) any later version. * 12 | #* for detail see the LICENCE text file. * 13 | #* * 14 | #* FreeCAD is distributed in the hope that it will be useful, * 15 | #* but WITHOUT ANY WARRANTY; without even the implied warranty of * 16 | #* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * 17 | #* GNU Lesser General Public License for more details. * 18 | #* * 19 | #* You should have received a copy of the GNU Library General Public * 20 | #* License along with FreeCAD; if not, write to the Free Software * 21 | #* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 * 22 | #* USA * 23 | #* * 24 | #***************************************************************************/ 25 | -------------------------------------------------------------------------------- /basic3_wb/InitGui.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | # FreeCAD init script of the Basic 3 module, 3 | # simple workbench, 3 commands 4 | 5 | #*************************************************************************** 6 | #* (c) Felipe Machado https://github.com/felipe-m 2017 * 7 | #* * 8 | #* This file is part of the FreeCAD CAx development system. * 9 | #* * 10 | #* This program is free software; you can redistribute it and/or modify * 11 | #* it under the terms of the GNU Lesser General Public License (LGPL) * 12 | #* as published by the Free Software Foundation; either version 2 of * 13 | #* the License, or (at your option) any later version. * 14 | #* for detail see the LICENCE text file. * 15 | #* * 16 | #* FreeCAD is distributed in the hope that it will be useful, * 17 | #* but WITHOUT ANY WARRANTY; without even the implied warranty of * 18 | #* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * 19 | #* GNU Lesser General Public License for more details. * 20 | #* * 21 | #* You should have received a copy of the GNU Library General Public * 22 | #* License along with FreeCAD; if not, write to the Free Software * 23 | #* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 * 24 | #* USA * 25 | #* * 26 | #***************************************************************************/ 27 | 28 | 29 | class Basic3Workbench (Workbench): 30 | """Basic 3 workbench object""" 31 | # this is the icon in XPM format 16x16 pixels 32 | Icon = """ 33 | /* XPM */ 34 | static char * basic3_xpm[] = { 35 | "16 16 7 1", 36 | " c None", 37 | ". c #FFFFFF", 38 | "+ c #000000", 39 | "@ c #7F4F00", 40 | "# c #FFBF00", 41 | "$ c #B88900", 42 | "% c #6E5200", 43 | "................", 44 | "...++++++++++++.", 45 | "..+@#########++.", 46 | ".+@#########+@+.", 47 | ".+++++++++++@#+.", 48 | ".+#########+##+.", 49 | ".+##$++$###+##+.", 50 | ".+##%#$+###+##+.", 51 | ".+####$+###+##+.", 52 | ".+###++$###+##+.", 53 | ".+####$+###+##+.", 54 | ".+##%#$+###+##+.", 55 | ".+##$++$###+#@+.", 56 | ".+#########+@+..", 57 | ".++++++++++++...", 58 | "................"}; 59 | """ 60 | MenuText = "Basic3" 61 | ToolTip = "Basic 3 workbench" 62 | 63 | def Initialize(self) : 64 | "This function is executed when FreeCAD starts" 65 | from PySide import QtCore, QtGui 66 | # python file where the commands are: 67 | import Basic3Gui 68 | # list of commands, just 3 (they are in the imported Basic3Gui): 69 | cmdlist = [ "Basic3_MakeBox", 70 | "Basic3_MakeBoxDialog", 71 | "Basic3_MakeBoxEdgeP"] 72 | self.appendToolbar( 73 | str(QtCore.QT_TRANSLATE_NOOP("Basic3", "Basic3")), cmdlist) 74 | self.appendMenu( 75 | str(QtCore.QT_TRANSLATE_NOOP("Basic3", "Basic3")), cmdlist) 76 | 77 | Log ('Loading Basic3 module... done\n') 78 | 79 | def GetClassName(self): 80 | return "Gui::PythonWorkbench" 81 | 82 | # The workbench is added 83 | Gui.addWorkbench(Basic3Workbench()) 84 | 85 | -------------------------------------------------------------------------------- /basic3_wb/icons/basic3_makebox_cmd.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 19 | 21 | 40 | 42 | 43 | 45 | image/svg+xml 46 | 48 | 49 | 50 | 51 | 52 | 57 | 64 | 69 | 75 | 76 | 77 | -------------------------------------------------------------------------------- /basic3_wb/icons/basic3_makeboxdialog_cmd.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 19 | 21 | 40 | 42 | 43 | 45 | image/svg+xml 46 | 48 | 49 | 50 | 51 | 52 | 57 | 64 | 69 | 75 | d 86 | 87 | 88 | -------------------------------------------------------------------------------- /basic3_wb/icons/basic3_makeboxedge_cmd.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 19 | 21 | 40 | 42 | 43 | 45 | image/svg+xml 46 | 48 | 49 | 50 | 51 | 52 | 57 | 64 | 69 | 75 | e 86 | 87 | 88 | -------------------------------------------------------------------------------- /basic4_wb/Basic4Gui.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | # FreeCAD script for the commands of the basic workbench creation tutorial 3 | # (c) 2017 Felipe Machado 4 | 5 | #*************************************************************************** 6 | #* (c) Felipe Machado 2017 * 7 | #* https://github.com/felipe-m/tutorial_freecad_wb * 8 | #* * 9 | #* This file is part of the FreeCAD CAx development system. * 10 | #* * 11 | #* This program is free software; you can redistribute it and/or modify * 12 | #* it under the terms of the GNU Lesser General Public License (LGPL) * 13 | #* as published by the Free Software Foundation; either version 2 of * 14 | #* the License, or (at your option) any later version. * 15 | #* for detail see the LICENCE text file. * 16 | #* * 17 | #* FreeCAD is distributed in the hope that it will be useful, * 18 | #* but WITHOUT ANY WARRANTY; without even the implied warranty of * 19 | #* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * 20 | #* GNU Lesser General Public License for more details. * 21 | #* * 22 | #* You should have received a copy of the GNU Library General Public * 23 | #* License along with FreeCAD; if not, write to the Free Software * 24 | #* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 * 25 | #* USA * 26 | #* * 27 | #***************************************************************************/ 28 | 29 | import PySide 30 | from PySide import QtCore, QtGui 31 | import FreeCAD 32 | import FreeCADGui 33 | import Part 34 | import os 35 | 36 | __dir__ = os.path.dirname(__file__) 37 | 38 | # FreeCAD Command made with a Python script 39 | def MakeBox(box_len = 1, box_wid = 1, box_hei = 1, boxname='box'): 40 | doc = FreeCAD.ActiveDocument 41 | box = doc.addObject("Part::Box",boxname) 42 | box.Length = box_len 43 | box.Width = box_wid 44 | box.Height = box_hei 45 | 46 | # GUI command that links the Python script 47 | class _MakeBoxCmd: 48 | """Command to create a box""" 49 | 50 | def Activated(self): 51 | # what is done when the command is clicked 52 | MakeBox() 53 | 54 | def GetResources(self): 55 | # icon and command information 56 | MenuText = QtCore.QT_TRANSLATE_NOOP( 57 | 'Basic4_Box', 58 | 'Box 1 1 1') 59 | ToolTip = QtCore.QT_TRANSLATE_NOOP( 60 | 'Basic4_Box', 61 | 'Creates a new box') 62 | return { 63 | 'Pixmap': __dir__ + '/icons/basic4_makebox_cmd.svg', 64 | 'MenuText': MenuText, 65 | 'ToolTip': ToolTip} 66 | 67 | def IsActive(self): 68 | # The command will be active if there is an active document 69 | return not FreeCAD.ActiveDocument is None 70 | 71 | # ---------- classes to make a box with a dialog 72 | 73 | # Task Panel creation: the task panel has to have: 74 | # 1. a widget called self.form 75 | # 2. reject and accept methods (if needed) 76 | class BoxSimpleTaskPanel: 77 | def __init__(self,widget): 78 | self.form = widget 79 | 80 | # Ok and Cancel buttons are created by default in FreeCAD Task Panels 81 | # What is done when we click on the ok button. 82 | def accept(self): 83 | MakeBox(boxname='box_dialog') 84 | FreeCADGui.Control.closeDialog() #close the dialog 85 | 86 | # What is done when we click on the cancel button. 87 | # commented because this is the default behaviour 88 | #def reject(self): 89 | # FreeCADGui.Control.closeDialog() 90 | 91 | # GUI command that links the Python script 92 | class _MakeBoxDialogCmd: 93 | """Command to create a box with a very simple dialog 94 | """ 95 | 96 | def Activated(self): 97 | # what is done when the command is clicked 98 | # creates a panel with a dialog 99 | baseWidget = QtGui.QWidget() 100 | panel = BoxSimpleTaskPanel(baseWidget) 101 | # having a panel with a widget in self.form and the accept and 102 | # reject functions (if needed), we can open it: 103 | FreeCADGui.Control.showDialog(panel) 104 | 105 | def GetResources(self): 106 | # icon and command information 107 | MenuText = QtCore.QT_TRANSLATE_NOOP( 108 | 'Basic4_DBox', 109 | 'Box Dialog') 110 | ToolTip = QtCore.QT_TRANSLATE_NOOP( 111 | 'Basic4_DBox', 112 | 'Creates a box using a task panel dialog') 113 | return { 114 | 'Pixmap': __dir__ + '/icons/basic4_makeboxdialog_cmd.svg', 115 | 'MenuText': MenuText, 116 | 'ToolTip': ToolTip} 117 | 118 | def IsActive(self): 119 | # The command will be active if there is an active document 120 | return not FreeCAD.ActiveDocument is None 121 | 122 | 123 | # classes to make a box with a dialog where the Edge length can be set 124 | 125 | # Task Panel creation: the task panel has to have: 126 | # 1. a widget called self.form 127 | # 2. reject and accept methods (if needed) 128 | class BoxEdgePTaskPanel: 129 | def __init__(self,widget): 130 | self.form = widget 131 | # The layout will be horizontal 132 | layout = QtGui.QHBoxLayout(self.form) 133 | # Label: 134 | self.edgeLabel = QtGui.QLabel("Cube's edge length (mm)") 135 | # Spin Box that takes doubles 136 | self.edgeValue = QtGui.QDoubleSpinBox() 137 | # Default value 138 | self.edgeValue.setValue(1) 139 | # suffix to indicate the units 140 | self.edgeValue.setSuffix(' mm') 141 | layout.addWidget(self.edgeLabel) 142 | layout.addWidget(self.edgeValue) 143 | #self.form.setLayout(layout) 144 | 145 | # Ok and Cancel buttons are created by default in FreeCAD Task Panels 146 | # What is done when we click on the ok button. 147 | def accept(self): 148 | edge_length = self.edgeValue.value() 149 | MakeBox(edge_length, edge_length, edge_length, 'box_edge') 150 | FreeCADGui.Control.closeDialog() #close the dialog 151 | 152 | # What is done when we click on the cancel button. 153 | # commented because this is the default behaviour 154 | #def reject(self): 155 | # FreeCADGui.Control.closeDialog() 156 | 157 | # GUI command that links the Python script 158 | class _MakeBoxEdgeP: 159 | """Command to create a box with a dialog where you can set the Edge length 160 | """ 161 | 162 | def Activated(self): 163 | # what is done when the command is clicked 164 | # creates a panel with a dialog 165 | baseWidget = QtGui.QWidget() 166 | panel = BoxEdgePTaskPanel(baseWidget) 167 | # having a panel with a widget in self.form and the accept and 168 | # reject functions (if needed), we can open it: 169 | FreeCADGui.Control.showDialog(panel) 170 | 171 | def GetResources(self): 172 | # icon and command information 173 | MenuText = QtCore.QT_TRANSLATE_NOOP( 174 | 'Basic4_EBox', 175 | 'Edge Parameter Box Dialog') 176 | ToolTip = QtCore.QT_TRANSLATE_NOOP( 177 | 'Basic4_EBox', 178 | 'Creates a box using a dialog to choose the edge length') 179 | return { 180 | 'Pixmap': __dir__ + '/icons/basic4_makeboxedge_cmd.svg', 181 | 'MenuText': MenuText, 182 | 'ToolTip': ToolTip} 183 | 184 | def IsActive(self): 185 | # The command will be active if there is an active document 186 | return not FreeCAD.ActiveDocument is None 187 | 188 | # classes to make a box with a dialog where the Length, Width and Height 189 | # can be set 190 | 191 | # Task Panel creation: the task panel has to have: 192 | # 1. a widget called self.form 193 | # 2. reject and accept methods (if needed) 194 | class BoxParamTaskPanel: 195 | def __init__(self,widget): 196 | self.form = widget 197 | # The layout will be a grid, since the form is an argument 198 | # we dont need this statement afterwards: self.form.setLayout(layout) 199 | layout = QtGui.QGridLayout(self.form) 200 | # ---- row 0: length 201 | # Label: 202 | self.lenLabel = QtGui.QLabel("Length:") 203 | # Spin Box that takes doubles 204 | self.lenValue = QtGui.QDoubleSpinBox() 205 | # Default value 206 | self.lenValue.setValue(1) 207 | # suffix to indicate the units 208 | self.lenValue.setSuffix(' mm') 209 | 210 | # row 0, column 0, rowspan 1, colspan 1 211 | layout.addWidget(self.lenLabel,0,0,1,1) 212 | # row 0, column 0, rowspan 1, colspan 1 213 | layout.addWidget(self.lenValue,0,1,1,1) 214 | 215 | # ---- row 1: width 216 | # Label: 217 | self.widLabel = QtGui.QLabel("Width:") 218 | # Spin Box that takes doubles 219 | self.widValue = QtGui.QDoubleSpinBox() 220 | # Default value 221 | self.widValue.setValue(1) 222 | # suffix to indicate the units 223 | self.widValue.setSuffix(' mm') 224 | 225 | # row 1, column 0, rowspan 1, colspan 1 226 | layout.addWidget(self.widLabel,1,0,1,1) 227 | # row 1, column 0, rowspan 1, colspan 1 228 | layout.addWidget(self.widValue,1,1,1,1) 229 | 230 | # ---- row 2: height 231 | # Label: 232 | self.heiLabel = QtGui.QLabel("Height:") 233 | # Spin Box that takes doubles 234 | self.heiValue = QtGui.QDoubleSpinBox() 235 | # Default value 236 | self.heiValue.setValue(1) 237 | # suffix to indicate the units 238 | self.heiValue.setSuffix(' mm') 239 | 240 | # row 2, column 0, rowspan 1, colspan 1 241 | layout.addWidget(self.heiLabel,2,0,1,1) 242 | # row 2, column 0, rowspan 1, colspan 1 243 | layout.addWidget(self.heiValue,2,1,1,1) 244 | 245 | 246 | 247 | # Ok and Cancel buttons are created by default in FreeCAD Task Panels 248 | # What is done when we click on the ok button. 249 | def accept(self): 250 | box_len = self.lenValue.value() 251 | box_wid = self.widValue.value() 252 | box_hei = self.heiValue.value() 253 | MakeBox(box_len, box_wid, box_hei, 'box_param') 254 | FreeCADGui.Control.closeDialog() #close the dialog 255 | 256 | # What is done when we click on the cancel button. 257 | # commented because this is the default behaviour 258 | #def reject(self): 259 | # FreeCADGui.Control.closeDialog() 260 | 261 | # GUI command that links the Python script 262 | class _MakeBoxParam: 263 | """Command to create a box with a dialog where you can set the Edge length 264 | """ 265 | 266 | def Activated(self): 267 | # what is done when the command is clicked 268 | # creates a panel with a dialog 269 | baseWidget = QtGui.QWidget() 270 | panel = BoxParamTaskPanel(baseWidget) 271 | # having a panel with a widget in self.form and the accept and 272 | # reject functions (if needed), we can open it: 273 | FreeCADGui.Control.showDialog(panel) 274 | 275 | def GetResources(self): 276 | # icon and command information 277 | MenuText = QtCore.QT_TRANSLATE_NOOP( 278 | 'Basic4_ParamBox', 279 | 'Parameter Box Dialog') 280 | ToolTip = QtCore.QT_TRANSLATE_NOOP( 281 | 'Basic4_ParamBox', 282 | 'Creates a box using a dialog to choose the dimensions') 283 | return { 284 | 'Pixmap': __dir__ + '/icons/basic4_makeboxparam_cmd.svg', 285 | 'MenuText': MenuText, 286 | 'ToolTip': ToolTip} 287 | 288 | def IsActive(self): 289 | # The command will be active if there is an active document 290 | return not FreeCAD.ActiveDocument is None 291 | 292 | 293 | 294 | 295 | 296 | 297 | FreeCADGui.addCommand('Basic4_MakeBox', _MakeBoxCmd()) 298 | FreeCADGui.addCommand('Basic4_MakeBoxDialog', _MakeBoxDialogCmd()) 299 | FreeCADGui.addCommand('Basic4_MakeBoxEdgeP', _MakeBoxEdgeP()) 300 | FreeCADGui.addCommand('Basic4_MakeBoxParam', _MakeBoxParam()) 301 | -------------------------------------------------------------------------------- /basic4_wb/Init.py: -------------------------------------------------------------------------------- 1 | # FreeCAD init script of BASIC1_WB module 2 | 3 | #*************************************************************************** 4 | #* (c) Felipe Machado https://github.com/felipe-m 2017 * 5 | #* * 6 | #* This file is part of the FreeCAD CAx development system. * 7 | #* * 8 | #* This program is free software; you can redistribute it and/or modify * 9 | #* it under the terms of the GNU Lesser General Public License (LGPL) * 10 | #* as published by the Free Software Foundation; either version 2 of * 11 | #* the License, or (at your option) any later version. * 12 | #* for detail see the LICENCE text file. * 13 | #* * 14 | #* FreeCAD is distributed in the hope that it will be useful, * 15 | #* but WITHOUT ANY WARRANTY; without even the implied warranty of * 16 | #* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * 17 | #* GNU Lesser General Public License for more details. * 18 | #* * 19 | #* You should have received a copy of the GNU Library General Public * 20 | #* License along with FreeCAD; if not, write to the Free Software * 21 | #* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 * 22 | #* USA * 23 | #* * 24 | #***************************************************************************/ 25 | -------------------------------------------------------------------------------- /basic4_wb/InitGui.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | # FreeCAD init script of the Basic 4 module, 3 | # simple workbench, 4 commands 4 | 5 | #*************************************************************************** 6 | #* (c) Felipe Machado https://github.com/felipe-m 2017 * 7 | #* * 8 | #* This file is part of the FreeCAD CAx development system. * 9 | #* * 10 | #* This program is free software; you can redistribute it and/or modify * 11 | #* it under the terms of the GNU Lesser General Public License (LGPL) * 12 | #* as published by the Free Software Foundation; either version 2 of * 13 | #* the License, or (at your option) any later version. * 14 | #* for detail see the LICENCE text file. * 15 | #* * 16 | #* FreeCAD is distributed in the hope that it will be useful, * 17 | #* but WITHOUT ANY WARRANTY; without even the implied warranty of * 18 | #* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * 19 | #* GNU Lesser General Public License for more details. * 20 | #* * 21 | #* You should have received a copy of the GNU Library General Public * 22 | #* License along with FreeCAD; if not, write to the Free Software * 23 | #* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 * 24 | #* USA * 25 | #* * 26 | #***************************************************************************/ 27 | 28 | 29 | class Basic4Workbench (Workbench): 30 | """Basic 4 workbench object""" 31 | # this is the icon in XPM format 16x16 pixels 32 | Icon = """ 33 | /* XPM */ 34 | static char * basic4_xpm[] = { 35 | "16 16 10 1", 36 | " c None", 37 | ". c #FFFFFF", 38 | "+ c #000000", 39 | "@ c #7F4F00", 40 | "# c #FFBF00", 41 | "$ c #684D00", 42 | "% c #EBB000", 43 | "& c #9F7700", 44 | "* c #D39E00", 45 | "= c #FBBC00", 46 | "................", 47 | "...++++++++++++.", 48 | "..+@#########++.", 49 | ".+@#########+@+.", 50 | ".+++++++++++@#+.", 51 | ".+#########+##+.", 52 | ".+####$+###+##+.", 53 | ".+###%++###+##+.", 54 | ".+###$&+###+##+.", 55 | ".+##*+=+###+##+.", 56 | ".+##+&#+###+##+.", 57 | ".+##+++++##+##+.", 58 | ".+#####+###+#@+.", 59 | ".+#########+@+..", 60 | ".++++++++++++...", 61 | "................"}; 62 | """ 63 | MenuText = "Basic4" 64 | ToolTip = "Basic 4 workbench" 65 | 66 | def Initialize(self) : 67 | "This function is executed when FreeCAD starts" 68 | from PySide import QtCore, QtGui 69 | # python file where the commands are: 70 | import Basic4Gui 71 | # list of commands, 4 (they are in the imported Basic4Gui): 72 | cmdlist = [ "Basic4_MakeBox", 73 | "Basic4_MakeBoxDialog", 74 | "Basic4_MakeBoxEdgeP", 75 | "Basic4_MakeBoxParam"] 76 | self.appendToolbar( 77 | str(QtCore.QT_TRANSLATE_NOOP("Basic4", "Basic4")), cmdlist) 78 | self.appendMenu( 79 | str(QtCore.QT_TRANSLATE_NOOP("Basic4", "Basic4")), cmdlist) 80 | 81 | Log ('Loading Basic4 module... done\n') 82 | 83 | def GetClassName(self): 84 | return "Gui::PythonWorkbench" 85 | 86 | # The workbench is added 87 | Gui.addWorkbench(Basic4Workbench()) 88 | 89 | -------------------------------------------------------------------------------- /basic4_wb/icons/basic4_makebox_cmd.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 19 | 21 | 40 | 42 | 43 | 45 | image/svg+xml 46 | 48 | 49 | 50 | 51 | 52 | 57 | 64 | 69 | 75 | 76 | 77 | -------------------------------------------------------------------------------- /basic4_wb/icons/basic4_makeboxdialog_cmd.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 19 | 21 | 40 | 42 | 43 | 45 | image/svg+xml 46 | 48 | 49 | 50 | 51 | 52 | 57 | 64 | 69 | 75 | d 86 | 87 | 88 | -------------------------------------------------------------------------------- /basic4_wb/icons/basic4_makeboxedge_cmd.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 19 | 21 | 40 | 42 | 43 | 45 | image/svg+xml 46 | 48 | 49 | 50 | 51 | 52 | 57 | 64 | 69 | 75 | e 86 | 87 | 88 | -------------------------------------------------------------------------------- /basic4_wb/icons/basic4_makeboxparam_cmd.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 19 | 21 | 40 | 42 | 43 | 45 | image/svg+xml 46 | 48 | 49 | 50 | 51 | 52 | 57 | 64 | 69 | 75 | P 86 | 87 | 88 | -------------------------------------------------------------------------------- /imgs/b1_wb.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 19 | 21 | 28 | 29 | 48 | 51 | 52 | 54 | 55 | 57 | image/svg+xml 58 | 60 | 61 | 62 | 63 | 64 | 69 | 76 | 81 | 87 | 1 98 | 99 | 100 | -------------------------------------------------------------------------------- /imgs/b1_wb.xcf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/felipe-m/tutorial_freecad_wb/f954a54b3024c12adbb9789842ffd58a1feb5611/imgs/b1_wb.xcf -------------------------------------------------------------------------------- /imgs/b1_wb.xpm: -------------------------------------------------------------------------------- 1 | /* XPM */ 2 | static char * C:\Users\felipe\urjc\proyectos\cad\py_freecad\tutorial_freecad_wb\imgs\b1_wb_2_xpm[] = { 3 | "16 16 5 1", 4 | " c None", 5 | ". c #FFFFFF", 6 | "+ c #000000", 7 | "@ c #7F4F00", 8 | "# c #FFBF00", 9 | "................", 10 | "...++++++++++++.", 11 | "..+@#########++.", 12 | ".+@#########+@+.", 13 | ".+++++++++++@#+.", 14 | ".+#########+##+.", 15 | ".+###++####+##+.", 16 | ".+####+####+##+.", 17 | ".+####+####+##+.", 18 | ".+####+####+##+.", 19 | ".+####+####+##+.", 20 | ".+####+####+##+.", 21 | ".+###+++###+#@+.", 22 | ".+#########+@+..", 23 | ".++++++++++++...", 24 | "................"}; 25 | -------------------------------------------------------------------------------- /imgs/b2_wb.xcf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/felipe-m/tutorial_freecad_wb/f954a54b3024c12adbb9789842ffd58a1feb5611/imgs/b2_wb.xcf -------------------------------------------------------------------------------- /imgs/b2_wb.xpm: -------------------------------------------------------------------------------- 1 | /* XPM */ 2 | static char * C:\Users\felipe\urjc\proyectos\cad\py_freecad\tutorial_freecad_wb\imgs\b2_wb_flat_xpm[] = { 3 | "16 16 8 1", 4 | " c None", 5 | ". c #FFFFFF", 6 | "+ c #000000", 7 | "@ c #6D5100", 8 | "# c #FFBF00", 9 | "$ c #B88900", 10 | "% c #E5AB00", 11 | "& c #FEBE00", 12 | "................", 13 | "...++++++++++++.", 14 | "..+@#########++.", 15 | ".+@#########+@+.", 16 | ".+++++++++++@#+.", 17 | ".+#########+##+.", 18 | ".+##$++$###+##+.", 19 | ".+##@%$+###+##+.", 20 | ".+####%+###+##+.", 21 | ".+###&+%###+##+.", 22 | ".+###+$####+##+.", 23 | ".+##+@#####+##+.", 24 | ".+##++++###+#@+.", 25 | ".+#########+@+..", 26 | ".++++++++++++...", 27 | "................"}; 28 | -------------------------------------------------------------------------------- /imgs/b2_wb_flat.xcf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/felipe-m/tutorial_freecad_wb/f954a54b3024c12adbb9789842ffd58a1feb5611/imgs/b2_wb_flat.xcf -------------------------------------------------------------------------------- /imgs/b3_wb.xcf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/felipe-m/tutorial_freecad_wb/f954a54b3024c12adbb9789842ffd58a1feb5611/imgs/b3_wb.xcf -------------------------------------------------------------------------------- /imgs/b3_wb.xpm: -------------------------------------------------------------------------------- 1 | /* XPM */ 2 | static char * C:\Users\felipe\urjc\proyectos\cad\py_freecad\tutorial_freecad_wb\imgs\b3_wb_xpm[] = { 3 | "16 16 7 1", 4 | " c None", 5 | ". c #FFFFFF", 6 | "+ c #000000", 7 | "@ c #7F4F00", 8 | "# c #FFBF00", 9 | "$ c #B88900", 10 | "% c #6E5200", 11 | "................", 12 | "...++++++++++++.", 13 | "..+@#########++.", 14 | ".+@#########+@+.", 15 | ".+++++++++++@#+.", 16 | ".+#########+##+.", 17 | ".+##$++$###+##+.", 18 | ".+##%#$+###+##+.", 19 | ".+####$+###+##+.", 20 | ".+###++$###+##+.", 21 | ".+####$+###+##+.", 22 | ".+##%#$+###+##+.", 23 | ".+##$++$###+#@+.", 24 | ".+#########+@+..", 25 | ".++++++++++++...", 26 | "................"}; 27 | -------------------------------------------------------------------------------- /imgs/b3_wb_flat.xcf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/felipe-m/tutorial_freecad_wb/f954a54b3024c12adbb9789842ffd58a1feb5611/imgs/b3_wb_flat.xcf -------------------------------------------------------------------------------- /imgs/b4_wb.xcf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/felipe-m/tutorial_freecad_wb/f954a54b3024c12adbb9789842ffd58a1feb5611/imgs/b4_wb.xcf -------------------------------------------------------------------------------- /imgs/b4_wb.xpm: -------------------------------------------------------------------------------- 1 | /* XPM */ 2 | static char * C:\Users\felipe\urjc\proyectos\cad\py_freecad\tutorial_freecad_wb\imgs\b4_wb_xpm[] = { 3 | "16 16 10 1", 4 | " c None", 5 | ". c #FFFFFF", 6 | "+ c #000000", 7 | "@ c #7F4F00", 8 | "# c #FFBF00", 9 | "$ c #684D00", 10 | "% c #EBB000", 11 | "& c #9F7700", 12 | "* c #D39E00", 13 | "= c #FBBC00", 14 | "................", 15 | "...++++++++++++.", 16 | "..+@#########++.", 17 | ".+@#########+@+.", 18 | ".+++++++++++@#+.", 19 | ".+#########+##+.", 20 | ".+####$+###+##+.", 21 | ".+###%++###+##+.", 22 | ".+###$&+###+##+.", 23 | ".+##*+=+###+##+.", 24 | ".+##+&#+###+##+.", 25 | ".+##+++++##+##+.", 26 | ".+#####+###+#@+.", 27 | ".+#########+@+..", 28 | ".++++++++++++...", 29 | "................"}; 30 | -------------------------------------------------------------------------------- /imgs/b4_wb_flat.xcf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/felipe-m/tutorial_freecad_wb/f954a54b3024c12adbb9789842ffd58a1feb5611/imgs/b4_wb_flat.xcf -------------------------------------------------------------------------------- /imgs/wb2_dialog.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/felipe-m/tutorial_freecad_wb/f954a54b3024c12adbb9789842ffd58a1feb5611/imgs/wb2_dialog.png -------------------------------------------------------------------------------- /imgs/wb2_toolbar.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/felipe-m/tutorial_freecad_wb/f954a54b3024c12adbb9789842ffd58a1feb5611/imgs/wb2_toolbar.png -------------------------------------------------------------------------------- /imgs/wb3_dialog.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/felipe-m/tutorial_freecad_wb/f954a54b3024c12adbb9789842ffd58a1feb5611/imgs/wb3_dialog.png -------------------------------------------------------------------------------- /imgs/wb3_toolbar.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/felipe-m/tutorial_freecad_wb/f954a54b3024c12adbb9789842ffd58a1feb5611/imgs/wb3_toolbar.png -------------------------------------------------------------------------------- /imgs/wb4_dialog.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/felipe-m/tutorial_freecad_wb/f954a54b3024c12adbb9789842ffd58a1feb5611/imgs/wb4_dialog.png -------------------------------------------------------------------------------- /imgs/wb_active.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/felipe-m/tutorial_freecad_wb/f954a54b3024c12adbb9789842ffd58a1feb5611/imgs/wb_active.png -------------------------------------------------------------------------------- /imgs/wb_active_name.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/felipe-m/tutorial_freecad_wb/f954a54b3024c12adbb9789842ffd58a1feb5611/imgs/wb_active_name.png -------------------------------------------------------------------------------- /imgs/wb_icon_sel.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/felipe-m/tutorial_freecad_wb/f954a54b3024c12adbb9789842ffd58a1feb5611/imgs/wb_icon_sel.png -------------------------------------------------------------------------------- /imgs/wb_icon_sel_name.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/felipe-m/tutorial_freecad_wb/f954a54b3024c12adbb9789842ffd58a1feb5611/imgs/wb_icon_sel_name.png -------------------------------------------------------------------------------- /imgs/wb_no_file.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/felipe-m/tutorial_freecad_wb/f954a54b3024c12adbb9789842ffd58a1feb5611/imgs/wb_no_file.png -------------------------------------------------------------------------------- /imgs/wb_no_file_name.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/felipe-m/tutorial_freecad_wb/f954a54b3024c12adbb9789842ffd58a1feb5611/imgs/wb_no_file_name.png -------------------------------------------------------------------------------- /imgs/wb_selection.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/felipe-m/tutorial_freecad_wb/f954a54b3024c12adbb9789842ffd58a1feb5611/imgs/wb_selection.png -------------------------------------------------------------------------------- /readme.md: -------------------------------------------------------------------------------- 1 | # Tutorials on how to create your own Python workbench in FreeCAD 2 | 3 | This is a series of tutorials to guide you on how to create your Python [workbench](https://www.freecadweb.org/wiki/Workbenches) in [FreeCAD](https://www.freecadweb.org) 4 | 5 | 1. [Tutorial 1](./tut_fwb_1.md): How to create a very simple Python Workbench with just one command 6 | 1. [Tutorial 2](./tut_fwb_2.md): How to create a create a very simple dialog for a Workbench command. Just two buttons: Ok - Cancel. *No improvement over the previous, just to learn how to have a dialog in the task panel* 7 | 1. [Tutorial 3](./tut_fwb_3.md): How to create a create a simple dialog for a Workbench command that includes an input box where a parameter can be set. 8 | 1. [Tutorial 4](./tut_fwb_4.md): Expand tutorial 3 to have 3 parameters to set. The form is arranged in a grid. 9 | 10 | -------------------------------------------------------------------------------- /tut_fwb_1.md: -------------------------------------------------------------------------------- 1 | # How to create your own Python workbench in FreeCAD 2 | 3 | ## Description 4 | You can create your own [FreeCAD](https://www.freecadweb.org) [workbench](https://www.freecadweb.org/wiki/Workbenches). 5 | 6 | In this tutorial you will learn how to create a very simple workbench using [python script commands](https://www.freecadweb.org/wiki/Introduction_to_Python) and making the interface with [PySide](https://www.freecadweb.org/wiki/PySide). 7 | 8 | In the next [tutorial](./tut_fwb_2.md) you will learn how to make a very simple dialog for a command of your FreeCAD workbench 9 | 10 | Check the [index](./readme.md) for more tutorials 11 | 12 | ## Introduction 13 | Power users have extended FreeCAD with various custom external workbenches that are not integrated in FreeCAD. 14 | You can check these external workbenches here: https://www.freecadweb.org/wiki/External_workbenches 15 | 16 | Information about installing workbenches can be found in the [FreeCAD documentation](https://www.freecadweb.org/wiki/Installing_more_workbenches) 17 | and in this [tutorial](https://www.freecadweb.org/wiki/How_to_install_additional_workbenches) 18 | 19 | You can create workbenches following this [FreeCAD documentation](https://www.freecadweb.org/wiki/Workbench_creation). 20 | 21 | Workbenches are containers for FreeCAD commands. These commands can be coded in Python or C++ 22 | 23 | This tutorial will lead you through the steps of the creation of a very simple workbench with Python commands. 24 | 25 | ## Single command Workbench 26 | 27 | Let us create a very simple workbench with just one command to create a box. 28 | Obviously, there is no need to create this workbench, since you have the [Part Box](https://www.freecadweb.org/wiki/Part_Box) command availabe in the [Part workbench](https://www.freecadweb.org/wiki/Part_Module) 29 | 30 | As explained in the [Workbech creation documentation](https://www.freecadweb.org/wiki/Workbench_creation), we have to create a folder, with any name we like, in the **Mod** directory. 31 | 32 | In this folder we are going to have 3 files: 33 | + Init.py 34 | + InitGui.py 35 | + Basic1Gui.py 36 | 37 | ### Init.py 38 | 39 | The file [Init.py](basic1_wb/Init.py) has no contents, you can just include your name (John Doe), the module name (we have called it BASIC1_WB) and the license: 40 | 41 | ```python 42 | # FreeCAD init script of BASIC1_WB module 43 | 44 | #*************************************************************************** 45 | #* (c) John Doe john@doe.com 2017 * 46 | #* * 47 | #* This file is part of the FreeCAD CAx development system. * 48 | #* * 49 | #* This program is free software; you can redistribute it and/or modify * 50 | #* it under the terms of the GNU Lesser General Public License (LGPL) * 51 | #* as published by the Free Software Foundation; either version 2 of * 52 | #* the License, or (at your option) any later version. * 53 | #* for detail see the LICENCE text file. * 54 | #* * 55 | #* FreeCAD is distributed in the hope that it will be useful, * 56 | #* but WITHOUT ANY WARRANTY; without even the implied warranty of * 57 | #* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * 58 | #* GNU Lesser General Public License for more details. * 59 | #* * 60 | #* You should have received a copy of the GNU Library General Public * 61 | #* License along with FreeCAD; if not, write to the Free Software * 62 | #* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 * 63 | #* USA * 64 | #* * 65 | #***************************************************************************/ 66 | ``` 67 | 68 | ### InitGui.py 69 | 70 | In the same folder, we are going to create another file called [InitGui.py](basic1_wb/InitGui.py). 71 | This file defines the workbench, which contains a name, an icon, and a series of FreeCAD commands. 72 | 73 | 74 | ```python 75 | 76 | class Basic1Workbench (Workbench): 77 | """Basic 1 workbench object""" 78 | # this is the icon in XPM format 16x16 pixels 79 | Icon = """ 80 | /* XPM */ 81 | static char * basic1_xpm[] = { 82 | "16 16 5 1", 83 | " c None", 84 | ". c #FFFFFF", 85 | "+ c #000000", 86 | "@ c #7F4F00", 87 | "# c #FFBF00", 88 | "................", 89 | "...++++++++++++.", 90 | "..+@#########++.", 91 | ".+@#########+@+.", 92 | ".+++++++++++@#+.", 93 | ".+#########+##+.", 94 | ".+###++####+##+.", 95 | ".+####+####+##+.", 96 | ".+####+####+##+.", 97 | ".+####+####+##+.", 98 | ".+####+####+##+.", 99 | ".+####+####+##+.", 100 | ".+###+++###+#@+.", 101 | ".+#########+@+..", 102 | ".++++++++++++...", 103 | "................"}; 104 | """ 105 | 106 | MenuText = "Basic1" 107 | ToolTip = "Basic 1 workbench" 108 | 109 | def Initialize(self) : 110 | "This function is executed when FreeCAD starts" 111 | from PySide import QtCore, QtGui 112 | # python file where the commands are: 113 | import Basic1Gui 114 | # list of commands, only one (it is in the imported Basic1Gui): 115 | cmdlist = [ "Basic1_MakeBox"] 116 | self.appendToolbar( 117 | str(QtCore.QT_TRANSLATE_NOOP("Basic1", "Basic1")), cmdlist) 118 | self.appendMenu( 119 | str(QtCore.QT_TRANSLATE_NOOP("Basic1", "Basic1")), cmdlist) 120 | 121 | Log ('Loading Basic1 module... done\n') 122 | 123 | def GetClassName(self): 124 | return "Gui::PythonWorkbench" 125 | 126 | # The workbench is added: 127 | Gui.addWorkbench(Basic1Workbench()) 128 | ``` 129 | 130 | So the class Basic1Workbench creates the basic workbench when called. 131 | 132 | ```python 133 | class Basic1Workbench (Workbench): 134 | ``` 135 | 136 | This example is very basic, check https://www.freecadweb.org/wiki/Workbench_creation for more information. 137 | 138 | Inside the class, an icon is created. This is the [workbench](https://www.freecadweb.org/wiki/Workbenches) icon that you will see on the workbench selection 139 | 140 | ![workbench selection](imgs/wb_selection.png) 141 | 142 | The icon is in XPM format (https://en.wikipedia.org/wiki/X_PixMap). 143 | It has 16x16 pixels and you can created it with [gimp](https://www.gimp.org/). 144 | Then open the saved file with a text editor and paste the image in the InitGui.py file. 145 | These are the files: 146 | + [b1_wb.xcf](imgs/b1_wb.xcf) 147 | + [b1_wb.xpm](imgs/b1_wb.xpm) 148 | 149 | ```python 150 | # this is the icon in XPM format 16x16 pixels 151 | Icon = """ 152 | /* XPM */ 153 | static char * basic1_xpm[] = { 154 | "16 16 5 1", 155 | " c None", 156 | ". c #FFFFFF", 157 | "+ c #000000", 158 | "@ c #7F4F00", 159 | "# c #FFBF00", 160 | "................", 161 | "...++++++++++++.", 162 | "..+@#########++.", 163 | ".+@#########+@+.", 164 | ".+++++++++++@#+.", 165 | ".+#########+##+.", 166 | ".+###++####+##+.", 167 | ".+####+####+##+.", 168 | ".+####+####+##+.", 169 | ".+####+####+##+.", 170 | ".+####+####+##+.", 171 | ".+####+####+##+.", 172 | ".+###+++###+#@+.", 173 | ".+#########+@+..", 174 | ".++++++++++++...", 175 | "................"}; 176 | """ 177 | ``` 178 | 179 | Then, we have the name of the workbench and a description: 180 | 181 | ```python 182 | MenuText = "Basic1" 183 | ToolTip = "Basic 1 workbench" 184 | ``` 185 | 186 | The method Initialize creates the Toolbar and the Menu for the new workbench 187 | Basic1Gui.py is imported because the command Basic1_MakeBox is defined there 188 | 189 | ```python 190 | def Initialize(self) : 191 | "This function is executed when FreeCAD starts" 192 | from PySide import QtCore, QtGui 193 | # python file where the commands are: 194 | import Basic1Gui 195 | # list of commands, only one (it is in the imported Basic1Gui): 196 | cmdlist = [ "Basic1_MakeBox"] 197 | self.appendToolbar( 198 | str(QtCore.QT_TRANSLATE_NOOP("Basic1", "Basic1")), cmdlist) 199 | self.appendMenu( 200 | str(QtCore.QT_TRANSLATE_NOOP("Basic1", "Basic1")), cmdlist) 201 | 202 | #FreeCADGui.addIconPath(":/icons") 203 | Log ('Loading Basic1 module... done\n') 204 | ``` 205 | 206 | The last line adds the workbench: 207 | 208 | ```python 209 | Gui.addWorkbench(Basic1Workbench()) 210 | ``` 211 | 212 | ### Basic1Gui.py 213 | 214 | [Basic1Gui.py](basic1_wb/Basic1Gui.py) defines the command Basic1_MakeBox: 215 | 216 | 217 | ```python 218 | import PySide 219 | from PySide import QtCore, QtGui 220 | import FreeCAD 221 | import FreeCADGui 222 | import os 223 | 224 | __dir__ = os.path.dirname(__file__) 225 | 226 | # FreeCAD Command made with a Python script 227 | def MakeBox(): 228 | doc = FreeCAD.ActiveDocument 229 | box = doc.addObject("Part::Box",'box') 230 | box.Length = 1 231 | box.Width = 1 232 | box.Height = 1 233 | 234 | # GUI command that links the Python script 235 | class _MakeBoxCmd: 236 | """Command to create a box""" 237 | 238 | def Activated(self): 239 | # what is done when the command is clicked 240 | MakeBox() 241 | 242 | def GetResources(self): 243 | # icon and command information 244 | MenuText = QtCore.QT_TRANSLATE_NOOP( 245 | 'Basic1_Box', 246 | 'Box') 247 | ToolTip = QtCore.QT_TRANSLATE_NOOP( 248 | 'Basic1_Box', 249 | 'Creates a new box') 250 | return { 251 | 'Pixmap': __dir__ + '/icons/basic1_makebox_cmd.svg', 252 | 'MenuText': MenuText, 253 | 'ToolTip': ToolTip} 254 | 255 | def IsActive(self): 256 | # The command will be active if there is an active document 257 | return not FreeCAD.ActiveDocument is None 258 | 259 | FreeCADGui.addCommand('Basic1_MakeBox', _MakeBoxCmd()) 260 | ``` 261 | 262 | 263 | So, what we have first is the function that makes a box, this is just a very simple python script that you can see here: https://www.freecadweb.org/wiki/Part_Box#Scripting 264 | 265 | We have named the box and also defined its dimensions: 266 | 267 | ```python 268 | # FreeCAD Command made with a Python script 269 | def MakeBox(): 270 | doc = FreeCAD.ActiveDocument 271 | box = doc.addObject("Part::Box",'box') 272 | box.Length = 1 273 | box.Width = 1 274 | box.Height = 1 275 | ``` 276 | 277 | Following we have the class for the command and links to the MakeBox funtion: 278 | 279 | ```python 280 | # GUI command that links the Python script 281 | class _MakeBoxCmd: 282 | """Command to create a box""" 283 | 284 | def Activated(self): 285 | # what is done when the command is clicked 286 | MakeBox() 287 | 288 | def GetResources(self): 289 | # icon and command information 290 | MenuText = QtCore.QT_TRANSLATE_NOOP( 291 | 'Basic1_Box', 292 | 'Box') 293 | ToolTip = QtCore.QT_TRANSLATE_NOOP( 294 | 'Basic1_Box', 295 | 'Creates a new box') 296 | return { 297 | 'Pixmap': __dir__ + '/icons/basic1_makebox_cmd.svg', 298 | 'MenuText': MenuText, 299 | 'ToolTip': ToolTip} 300 | 301 | def IsActive(self): 302 | # The command will be active if there is an active document 303 | return not FreeCAD.ActiveDocument is None 304 | ``` 305 | 306 | There are 3 methods: 307 | 1. Activated 308 | 1. GetResources 309 | 1. IsActive 310 | 311 | #### Activated 312 | This method is called when we click on the command icon (see the command icon with a red square following image) 313 | 314 | For this example we just call the MakeBox function: 315 | 316 | ![command icon](imgs/wb_icon_sel_name.png) 317 | 318 | 319 | #### GetResources 320 | This method indicates the name, information and the icon for the command. 321 | The icon is a 64x64 svg file [basic1_makebox_cmd.svg](basic1_wb/icons/basic1_makebox_cmd.svg). 322 | 323 | You can create this kind of icons with [inkscape](https://inkscape.org) 324 | 325 | Check the color code for icons here: https://www.freecadweb.org/wiki/Gui_Command#Icons 326 | 327 | #### IsActive 328 | This method indicates the conditions that make the command active. 329 | In our case, it will be active when there is an active document, so we can place the box in it. If not, it will be disabled. 330 | 331 | This is what happens when there is no active file: 332 | ![wb_nofile_icon](imgs/wb_no_file_name.png) 333 | 334 | This is what happens once we have opened/created a FreeCAD file: 335 | 336 | 337 | ![wb_file_icon](imgs/wb_active_name.png) 338 | 339 | --- 340 | 341 | In the last line of Basic1Gui.py, the command is added, and the link is made with the name on InitGui and the class in Basic1Gui.py 342 | 343 | ```python 344 | FreeCADGui.addCommand('Basic1_MakeBox', _MakeBoxCmd()) 345 | ``` 346 | 347 | ## File structure 348 | 349 | Now we have to copy these files in your user's FreeCAD Mod folder: 350 | ``` 351 | Mod/ 352 | +-- Basic1/ 353 | +-- Init.py 354 | +-- InitGui.py 355 | +-- Basic1Gui.py 356 | +-- icons/ 357 | +-- basic1_makebox_cmd.svg 358 | ``` 359 | 360 | Your user's FreeCAD folder location is obtained by typing in FreeCAD's python console: 361 | 362 | ```python 363 | FreeCAD.ConfigGet("UserAppData") 364 | ``` 365 | 366 | By doing this we will have our own very simple workbench 367 | 368 | --- 369 | 370 | Now, if you want to know how to make a very simple dialog, check 371 | how to create a very simple dialog in a FreeCAD workbench in the next [tutorial](./tut_fwb_2.md) 372 | 373 | 374 | 375 | 376 | -------------------------------------------------------------------------------- /tut_fwb_2.md: -------------------------------------------------------------------------------- 1 | # How to create a very simple dialog for a command in FreeCAD 2 | 3 | ## Description 4 | In the previous [tutorial](./tut_fwb_1.md) we learned how to create your FreeCAD Workbench and how to add a command to create a box. 5 | 6 | Now we are going to add a very simple dialog that will do the same. 7 | This approach does not offer any improvement from the previous, but will allow us to learn how to make dialogs for the next tutorials 8 | 9 | The information of this tutorial has been obtained from the FreeCAD website and in particular this [page](https://www.freecadweb.org/wiki/Manual:Creating_interface_tools) 10 | 11 | Check the [index](./readme.md) for more tutorials 12 | 13 | ## Introduction 14 | We are going to have the files in a different folder named Basic2 15 | 16 | ``` 17 | Mod/ 18 | +-- Basic2/ 19 | +-- Init.py 20 | +-- InitGui.py 21 | +-- Basic2Gui.py 22 | +-- icons/ 23 | +-- basic2_makebox_cmd.svg 24 | +-- basic2_makeboxdialog_cmd.svg 25 | ``` 26 | 27 | ## Simple dialog command 28 | 29 | We are going to add a command with a very simple dialog to our previous workbench 30 | 31 | ### Init.py 32 | 33 | The file [Init.py](basic2_wb/Init.py) will be the same as in Basic1 Workbench 34 | 35 | ### InitGui.py 36 | 37 | We are going to make modifications to the [InitGui.py](basic2_wb/InitGui.py). 38 | 39 | The icon, MenuText and ToolTip are different. Check the file to see what is different. 40 | 41 | For this workbench, the Initialize function will have 2 commands: 42 | - Basic2_MakeBox 43 | - Basic2_MakeBoxDialog 44 | 45 | Basic2_MakeBox is the same as in Basic1 (only the name has been changed) 46 | 47 | Basic2_MakeBoxDialog is the new command that we are introducing. As we will see, this command will have a dialog in the Task Panel. 48 | 49 | We are only going to review the main difference in the Initialize method. 50 | This difference is that now **cmdlist** has 2 elements, which are the 2 commands that our workbench will have. 51 | 52 | ```python 53 | 54 | def Initialize(self) : 55 | "This function is executed when FreeCAD starts" 56 | from PySide import QtCore, QtGui 57 | # python file where the commands are: 58 | import Basic2Gui 59 | # list of commands, just 2 (they are in Basic2Gui): 60 | cmdlist = [ "Basic2_MakeBox", "Basic2_MakeBoxDialog"] 61 | self.appendToolbar( 62 | str(QtCore.QT_TRANSLATE_NOOP("Basic2", "Basic2")), cmdlist) 63 | self.appendMenu( 64 | str(QtCore.QT_TRANSLATE_NOOP("Basic2", "Basic2")), cmdlist) 65 | 66 | Log ('Loading Basic2 module... done\n') 67 | 68 | ``` 69 | 70 | The rest of the code is basically the same as in Basic1/InitGui.py as explained in the previous [tutorial](./tut_fwb_1.md) 71 | 72 | ### Basic2Gui.py 73 | 74 | [Basic2Gui.py](basic2_wb/Basic2Gui.py) defines the 2 commands of our workbench: 75 | 1. Basic2_MakeBox: 76 | 1. Basic2_MakeBoxDialog: 77 | 78 | Basic2_MakeBox is the same as in Basic1, so we will skip that. We included it to have a workbench with 2 commands. 79 | 80 | ![workbench toolbar](imgs/wb2_toolbar.png) 81 | 82 | 83 | We are going to review the code for Basic2_MakeBoxDialog 84 | 85 | 86 | ```python 87 | 88 | # Task Panel creation, the task panel has to have: 89 | # 1. a widget called self.form 90 | # 2. reject and accept methods (if needed) 91 | class BoxSimpleTaskPanel: 92 | def __init__(self,widget): 93 | self.form = widget 94 | 95 | # Ok and Cancel buttons are created by default in FreeCAD Task Panels 96 | # What is done when we click on the ok button. 97 | def accept(self): 98 | MakeBox() 99 | FreeCADGui.Control.closeDialog() #close the dialog 100 | 101 | # What is done when we click on the cancel button. 102 | # commented because this is the default behaviour 103 | #def reject(self): 104 | # FreeCADGui.Control.closeDialog() 105 | 106 | # GUI command that links the Python script 107 | class _MakeBoxDialogCmd: 108 | """Command to create a box with a Ok Cancel buttons 109 | """ 110 | 111 | def Activated(self): 112 | # what is done when the command is clicked 113 | # creates a panel with a dialog 114 | baseWidget = QtGui.QWidget() 115 | panel = BoxSimpleTaskPanel(baseWidget) 116 | # having a panel with a widget in self.form and the accept and 117 | # reject functions (if needed), we can open it: 118 | FreeCADGui.Control.showDialog(panel) 119 | 120 | def GetResources(self): 121 | # icon and command information 122 | MenuText = QtCore.QT_TRANSLATE_NOOP( 123 | 'Basic2_DBox', 124 | 'Box Dialog') 125 | ToolTip = QtCore.QT_TRANSLATE_NOOP( 126 | 'Basic2_DBox', 127 | 'Creates a box using a task panel dialog') 128 | return { 129 | 'Pixmap': __dir__ + '/icons/basic2_makeboxdialog_cmd.svg', 130 | 'MenuText': MenuText, 131 | 'ToolTip': ToolTip} 132 | 133 | def IsActive(self): 134 | # The command will be active if there is an active document 135 | return not FreeCAD.ActiveDocument is None 136 | 137 | FreeCADGui.addCommand('Basic2_MakeBoxDialog', _MakeBoxDialogCmd()) 138 | 139 | ``` 140 | 141 | As we have seen in the previous tutorial the class **_MakeBoxDialogCmd** links the command with the Python script. 142 | 143 | When we click on the command the method **Activated** is called. 144 | 145 | ```python 146 | def Activated(self): 147 | # what is done when the command is clicked 148 | # creates a panel with a dialog 149 | baseWidget = QtGui.QWidget() 150 | panel = BoxSimpleTaskPanel(baseWidget) 151 | # having a panel with a widget in self.form and the accept and 152 | # reject functions (if needed), we can open it: 153 | FreeCADGui.Control.showDialog(panel) 154 | ``` 155 | 156 | In this method, a widget is created (baseWidget) 157 | 158 | This widget is passed as an argument for the function BoxSimpleTaskPanel, and we get the object **panel** 159 | 160 | We can open the task panel with the **panel** dialog: 161 | ```python 162 | FreeCADGui.Control.showDialog(panel) 163 | ``` 164 | 165 | FreeCADGui.Control is the Control Task Dialog 166 | 167 | 168 | #### BoxSimpleTaskPanel 169 | 170 | This class creates a very simple Task Panel: 171 | 172 | ```python 173 | 174 | class BoxSimpleTaskPanel: 175 | def __init__(self,widget): 176 | self.form = widget 177 | 178 | def accept(self): 179 | MakeBox() 180 | FreeCADGui.Control.closeDialog() #close the dialog 181 | ``` 182 | 183 | It just assigns the widget passed as argument to the attribute *form* 184 | 185 | And defines what it is going to do when the Ok button is clicked. 186 | It will make the box (see [tutorial](./tut_fwb_1.md) and close the Dialog. 187 | 188 | You can also include what happens when the **Cancel** button is pressed. 189 | In this case, since we have not include it, it will just do nothing and close the dialog. It would have been the same as adding the **reject** method to BoxSimpleTaskPanel: 190 | 191 | ```python 192 | 193 | def reject(self): 194 | FreeCADGui.Control.closeDialog() 195 | ``` 196 | 197 | So if we click on the Simple Dialog Command we will get the following Task Panel Dialog: 198 | 199 | ![Simple Task Panel Dialog selection](imgs/wb2_dialog.png) 200 | 201 | If we click in **Ok**, we will get a new cube. 202 | 203 | So it is nothing new, but in the next tutorial we will learn how to add parameters to the dialog 204 | -------------------------------------------------------------------------------- /tut_fwb_3.md: -------------------------------------------------------------------------------- 1 | # How to create a simple dialog to set a parameter 2 | 3 | ## Description 4 | In the second [tutorial](./tut_fwb_2.md) we learned how to create a dialog for a FreeCAD command Workbench. 5 | 6 | Now we are going to include an input box in the dialog to be able to set the length of the edges we are going to create 7 | 8 | Check the [index](./readme.md) for more tutorials 9 | 10 | ## Introduction 11 | We are going to have the files in a different folder named Basic3 12 | 13 | ``` 14 | Mod/ 15 | +-- Basic3/ 16 | +-- Init.py 17 | +-- InitGui.py 18 | +-- Basic3Gui.py 19 | +-- icons/ 20 | +-- basic3_makebox_cmd.svg 21 | +-- basic3_makeboxdialog_cmd.svg 22 | +-- basic3_makeboxedge_cmd.svg 23 | ``` 24 | 25 | ## Dialog with an input box 26 | 27 | We are going to add a label and an input box to the dialog to set the length of the edges 28 | 29 | ### Init.py 30 | 31 | The file [Init.py](basic3_wb/Init.py) will be the same as in the previous Workbenches 32 | 33 | ### InitGui.py 34 | 35 | We are going to make modifications to the [InitGui.py](basic3_wb/InitGui.py). 36 | 37 | The icon, MenuText and ToolTip are different. Check the source file to see what is different. 38 | 39 | For this workbench, the **Initialize** function will have 3 commands: 40 | - Basic3_MakeBox 41 | - Basic3_MakeBoxDialog 42 | - Basic3_MakeBoxEdgeP 43 | 44 | Basic3_MakeBox and Basic3_MakeBoxDialog are the same as in Basic2 (only the name has been changed) 45 | 46 | Basic3_MakeBoxEdgeP is the new command that we are introducing. 47 | So now we have to update **cmdlist** to have 3 elements, which are the 3 commands that our workbench will have. 48 | 49 | ```python 50 | 51 | def Initialize(self) : 52 | "This function is executed when FreeCAD starts" 53 | from PySide import QtCore, QtGui 54 | # python file where the commands are: 55 | import Basic3Gui 56 | # list of commands, just 3 (they are in the imported Basic3Gui): 57 | cmdlist = [ "Basic3_MakeBox", 58 | "Basic3_MakeBoxDialog", 59 | "Basic3_MakeBoxEdgeP"] 60 | self.appendToolbar( 61 | str(QtCore.QT_TRANSLATE_NOOP("Basic3", "Basic3")), cmdlist) 62 | self.appendMenu( 63 | str(QtCore.QT_TRANSLATE_NOOP("Basic3", "Basic3")), cmdlist) 64 | 65 | 66 | ``` 67 | 68 | The rest of the code is basically the same as in Basic1/InitGui.py as explained in the first [tutorial](./tut_fwb_1.md) 69 | 70 | ### Basic3Gui.py 71 | 72 | [Basic3Gui.py](basic3_wb/Basic3Gui.py) defines the 3 commands of our workbench: 73 | 1. Basic3_MakeBox 74 | 1. Basic3_MakeBoxDialog 75 | 1. Basic3_MakeBoxEdgeP 76 | 77 | Basic3_MakeBox and Basic3_MakeBoxDialog are the same as in Basic2, so we will skip the explanation. We included them to have a workbench with 3 commands. 78 | 79 | ![workbench toolbar](imgs/wb3_toolbar.png) 80 | 81 | 82 | We are going to review the code for Basic3_MakeBoxEdgeP 83 | 84 | 85 | ```python 86 | 87 | class BoxEdgePTaskPanel: 88 | def __init__(self,widget): 89 | self.form = widget 90 | layout = QtGui.QHBoxLayout() 91 | self.edgeLabel = QtGui.QLabel("Cube's edge length (mm)") 92 | # The layout will be horizontal 93 | # Spin Box that takes doubles 94 | self.edgeValue = QtGui.QDoubleSpinBox() 95 | # Default value 96 | self.edgeValue.setValue(1) 97 | # suffix to indicate the units 98 | self.edgeValue.setSuffix(' mm') 99 | layout.addWidget(self.edgeLabel) 100 | layout.addWidget(self.edgeValue) 101 | self.form.setLayout(layout) 102 | 103 | # Ok and Cancel buttons are created by default in FreeCAD Task Panels 104 | # What is done when we click on the ok button. 105 | def accept(self): 106 | edge_length = self.edgeValue.value() 107 | MakeBox(edge_length, 'box_edge') 108 | FreeCADGui.Control.closeDialog() #close the dialog 109 | 110 | # What is done when we click on the cancel button. 111 | # commented because this is the default behaviour 112 | #def reject(self): 113 | # FreeCADGui.Control.closeDialog() 114 | 115 | # GUI command that links the Python script 116 | class _MakeBoxEdgeP: 117 | """Command to create a box with a dialog where you can set the Edge length 118 | """ 119 | 120 | def Activated(self): 121 | # what is done when the command is clicked 122 | # creates a panel with a dialog 123 | baseWidget = QtGui.QWidget() 124 | panel = BoxEdgePTaskPanel(baseWidget) 125 | # having a panel with a widget in self.form and the accept and 126 | # reject functions (if needed), we can open it: 127 | FreeCADGui.Control.showDialog(panel) 128 | 129 | def GetResources(self): 130 | # icon and command information 131 | MenuText = QtCore.QT_TRANSLATE_NOOP( 132 | 'Basic3_PBox', 133 | 'Edge Parameter Box Dialog') 134 | ToolTip = QtCore.QT_TRANSLATE_NOOP( 135 | 'Basic3_PBox', 136 | 'Creates a box using a dialog to choose the edge length') 137 | return { 138 | 'Pixmap': __dir__ + '/icons/basic3_makeboxedge_cmd.svg', 139 | 'MenuText': MenuText, 140 | 'ToolTip': ToolTip} 141 | 142 | def IsActive(self): 143 | # The command will be active if there is an active document 144 | return not FreeCAD.ActiveDocument is None 145 | 146 | 147 | FreeCADGui.addCommand('Basic3_MakeBoxEdgeP', _MakeBoxEdgeP()) 148 | 149 | ``` 150 | 151 | The class **_MakeBoxEdgeP** is very similar to the previous [tutorial](./tut_fwb_2.md) 152 | 153 | The main difference is in the class **BoxEdgePTaskPanel**. This class creates the task panel. 154 | 155 | Compared to the task panel of the previous tutorial, now we add a Label and a Spin Box. To add them, first we include a **QHBoxLayout** to line the label and the Spin Box horizontally: 156 | 157 | ```python 158 | layout = QtGui.QHBoxLayout() 159 | ``` 160 | 161 | Then we add the label: 162 | 163 | ```python 164 | self.edgeLabel = QtGui.QLabel("Cube's edge length (mm)") 165 | ``` 166 | 167 | Next, the spin box, where we also set the default value, and a suffix for the units (milimetres) 168 | 169 | ```python 170 | self.edgeValue = QtGui.QDoubleSpinBox() 171 | # Default value 172 | self.edgeValue.setValue(1) 173 | # suffix to indicate the units 174 | self.edgeValue.setSuffix(' mm') 175 | ``` 176 | 177 | Last we add the label and the spinbox to the layout, and set the layout of the widget: 178 | 179 | ```python 180 | layout.addWidget(self.edgeLabel) 181 | layout.addWidget(self.edgeValue) 182 | self.form.setLayout(layout) 183 | ``` 184 | 185 | --- 186 | 187 | If the **Ok** button is clicked, we have to get the value introduced in the spin box, we do that in the **accept** method: 188 | 189 | ```python 190 | def accept(self): 191 | edge_length = self.edgeValue.value() 192 | MakeBox(edge_length, 'box_edge') 193 | FreeCADGui.Control.closeDialog() #close the dialog 194 | ``` 195 | 196 | --- 197 | 198 | Take into account that we need to modify the function **MakeBox** to accept arguments: 199 | 200 | 201 | ```python 202 | def MakeBox(edge_len = 1, boxname='box'): 203 | doc = FreeCAD.ActiveDocument 204 | box = doc.addObject("Part::Box",boxname) 205 | box.Length = edge_len 206 | box.Width = edge_len 207 | box.Height = edge_len 208 | ``` 209 | 210 | So if we click on the MakeBoxEdgeP Command we will get the following Task Panel Dialog: 211 | 212 | ![Simple Task Panel Dialog selection](imgs/wb3_dialog.png) 213 | 214 | We can set the length of the edges, and clicking on **Ok** we will get a new cube with the chosen dimension. 215 | 216 | ------ 217 | 218 | Check [tutorial 4](./tut_fwb_4.md) to see an example where 3 parameters are set. 219 | 220 | -------------------------------------------------------------------------------- /tut_fwb_4.md: -------------------------------------------------------------------------------- 1 | # How to create a dialog to set 3 parameters 2 | 3 | ## Description 4 | In this example we will have 3 parameters to set: Length, Width and Height 5 | 6 | There is not much else to explain if you have seen the previous tutorials. See the source code of [Basic4Gui.py](basic4_wb/Basic4Gui.py). It includes comments to understand the grid used to arrange the labels and input boxes. 7 | 8 | 9 | 10 | 11 | 12 | If you don't understand anything, check the [index](./readme.md) to see the previous tutorials 13 | 14 | By clicking on the parametric command, we will get the following dialog: 15 | 16 | ![Parametric Task Panel Dialog selection](imgs/wb4_dialog.png) 17 | 18 | *Note: In the image, the decimal point is a comma because of the regional/language computer configuration* 19 | 20 | We can set the length of each edge, by clicking on **Ok** we will get a new cube with the chosen dimension. 21 | 22 | 23 | 24 | These are the files of this tutorial: 25 | 26 | --------- 27 | 28 | Mod/ 29 | 30 | +-- basic4_wb/ 31 | 32 | +---- [Init.py](basic4_wb/Init.py) 33 | 34 | +---- [InitGui.py](basic4_wb/InitGui.py) 35 | 36 | +---- [Basic4Gui.py](basic4_wb/Basic4Gui.py) 37 | 38 | +---- icons/ 39 | 40 | +------- [basic4_makebox_cmd.svg](basic4_wb/icons/basic4_makebox_cmd.svg) ![basic4_makebox_cmd.svg](basic4_wb/icons/basic4_makebox_cmd.svg) 41 | 42 | +------- [basic4_makeboxdialog_cmd.svg](basic4_wb/icons/basic4_makeboxdialog_cmd.svg) ![basic4_makeboxdialog_cmd.svg](basic4_wb/icons/basic4_makeboxdialog_cmd.svg) 43 | 44 | +------- [basic4_makeboxedge_cmd.svg](basic4_wb/icons/basic4_makeboxedge_cmd.svg) ![basic4_makeboxedge_cmd.svg](basic4_wb/icons/basic4_makeboxedge_cmd.svg) 45 | 46 | +------- [basic4_makeboxparam_cmd.svg](basic4_wb/icons/basic4_makeboxparam_cmd.svg) ![basic4_makeboxparam_cmd.svg](basic4_wb/icons/basic4_makeboxparam_cmd.svg) 47 | 48 | 49 | --------- 50 | 51 | --------------------------------------------------------------------------------