Reload Workbenches for Development

Here's the place for discussion related to coding in FreeCAD, C++ or Python. Design, interfaces and structures.
Forum rules
Be nice to others! Respect the FreeCAD code of conduct!
usbhub
Posts: 280
Joined: Tue Apr 02, 2019 8:22 pm
Location: Earth

Reload Workbenches for Development

Post by usbhub »

Hello,
sorry for my newbie questions :roll:

I'm programming my first bigger workbench and if I make a change in the code, I have to restart FreeCAD completly. I searched through the forum and found this old thread https://forum.freecadweb.org/viewtopic.php?t=320. If I understood right, if you do things in the GUI manually, a simple reload doesn't work.
But the thread is 10 years old and so I ask again, if there is another, better possibility already? What are developers of FEM or TechDraw doing?

PS: If not, maybe a script/maco exist, that restarts FreeCAD automatically and load the right workbench and opened model again?
wmayer
Founder
Posts: 20242
Joined: Thu Feb 19, 2009 10:32 am
Contact:

Re: Reload Workbenches for Development

Post by wmayer »

Let's consider a simple workbench called MyTestWorkbench with this code in its InitGui.py file:

Code: Select all

class MyTestWorkbench (Workbench):
    "Mesh workbench object"
    def __init__(self):
        self.__class__.Icon = FreeCAD.getResourceDir() + "Mod/Mesh/Resources/icons/MeshWorkbench.svg"
        self.__class__.MenuText = "My Test workbench"
        self.__class__.ToolTip = "My Test workbench"

    def Initialize(self):
        pass

    def Activated(self):
        import MyTest
        print (dir(MyTest))

Gui.addWorkbench(MyTestWorkbench())
This file is executed at start of FreeCAD and an instance of the workbench class is created and registered to the application. If you now make changes to this InitGui.py file then this won't affect the already created instance. You have to unregister the workbench first and then re-execute the code.

If you instead make changes to the module MyTest.py then the procedure is simpler. In the Python console you have to enter import MyTest and then reload it again with:

Code: Select all

from importlib import reload
reload(MyTest)
Assuming you have added a new top-level function to MyTest.py then the next time you activate your workbench you will see it in the output window.
chrisb
Veteran
Posts: 53920
Joined: Tue Mar 17, 2015 9:14 am

Re: Reload Workbenches for Development

Post by chrisb »

You need an additional step. Here an example for generic_post.py:

Code: Select all

import generic_post
from importlib import reload
reload(generic_post)
A Sketcher Lecture with in-depth information is available in English, auf Deutsch, en français, en español.
User avatar
Kunda1
Veteran
Posts: 13434
Joined: Thu Jan 05, 2017 9:03 pm

Re: Reload Workbenches for Development

Post by Kunda1 »

Is this documented somewhere?
Alone you go faster. Together we go farther
Please mark thread [Solved]
Want to contribute back to FC? Checkout:
'good first issues' | Open TODOs and FIXMEs | How to Help FreeCAD | How to report Bugs
vocx
Veteran
Posts: 5197
Joined: Thu Oct 18, 2018 9:18 pm

Re: Reload Workbenches for Development

Post by vocx »

wmayer wrote: Tue Mar 03, 2020 6:18 pm ...
This file is executed at start of FreeCAD and an instance of the workbench class is created and registered to the application. If you now make changes to this InitGui.py file then this won't affect the already created instance. You have to unregister the workbench first and then re-execute the code.
I think the question is more about the graphical user interface. That is, what happens if you already defined toolbars and context menus in the Initialize method.

Code: Select all

    def Initialize(self):
        # Some code here that creates toolbars
        pass
Then what? Can this code be re-initialized. Can the workbench be completely unregistered, and its InitGui.py loaded again? That's the basic premise.

Is there something like the following?

Code: Select all

FreeCADGui.removeWorkbench("MyWorkbench")
FreeCADGui.reloadWorkbench("src/Mod/MyWorkbench/InitGui.py")
If you instead make changes to the module MyTest.py then the procedure is simpler. In the Python console you have to enter import MyTest and then reload it again...
Reloading a single Python module is not a big deal. But what if you have set up other things in Initialize, in ContextMenu, in Deactivated, etc?

Can the entire GUI setup (appendToolbar, appendContextMenu, addPreferencesPage) be included in a single Python module, so the entire interface can be reloaded?

Code: Select all

    def Activated(self):
        import MyTest # this module sets up all toolbars, context menus, preferences pages, as well as the individual commands
        print(dir(MyTest))
Always add the important information to your posts if you need help. Also see Tutorials and Video tutorials.
To support the documentation effort, and code development, your donation is appreciated: liberapay.com/FreeCAD.
usbhub
Posts: 280
Joined: Tue Apr 02, 2019 8:22 pm
Location: Earth

Re: Reload Workbenches for Development

Post by usbhub »

Hello,
thanks a lot to everybody! I will try it out and report to you :)
usbhub
Posts: 280
Joined: Tue Apr 02, 2019 8:22 pm
Location: Earth

Re: Reload Workbenches for Development

Post by usbhub »

Sorry for may late reply, but now I tested it:
I tried the version from crisb, but it doesn't work. In the InitGui.py I load ExportCommand, but when I reload it, the changes in ExportCommand aren't applied :/

I used this to reimport the module (the workbench was already activated/selected)

Code: Select all

import ExportCommand
from importlib import reload
reload(ExportCommand)
My FreeCAD version:

Code: Select all

OS: Linux Mint 19 (X-Cinnamon/cinnamon)
Word size of OS: 64-bit
Word size of FreeCAD: 64-bit
Version: 0.19.
Build type: Release
Python version: 3.6.9
Qt version: 5.9.5
Coin version: 4.0.0a
OCC version: 7.3.0
Locale: German/Germany (de_DE)
User avatar
DeepSOIC
Veteran
Posts: 7896
Joined: Fri Aug 29, 2014 12:45 am
Location: used to be Saint-Petersburg, Russia

Re: Reload Workbenches for Development

Post by DeepSOIC »

I had little luck with reloading.
I have set up a full-blown system to reload the whole Part-o-magic with one command. It kinda worked, but commands stop working. I don't really know why.

The effort of setting up such a system outweighs the inconvenience of having to restart FreeCAD every time, and doesn't even work properly in many situations (e.g., you need yet another system to scan and update proxy instances of parametric objects)... So my recommendation is: use reload only for isolated module that you test by running its methods from py console. For everything else, it's a waste of time.
usbhub
Posts: 280
Joined: Tue Apr 02, 2019 8:22 pm
Location: Earth

Re: Reload Workbenches for Development

Post by usbhub »

DeepSOIC wrote: Sat Mar 21, 2020 8:16 pm I had little luck with reloading.
I have set up a full-blown system to reload the whole Part-o-magic with one command. It kinda worked, but commands stop working. I don't really know why.

The effort of setting up such a system outweighs the inconvenience of having to restart FreeCAD every time, and doesn't even work properly in many situations (e.g., you need yet another system to scan and update proxy instances of parametric objects)... So my recommendation is: use reload only for isolated module that you test by running its methods from py console. For everything else, it's a waste of time.
Okay, that sounds not so good :(

But is there a way, that you can restart FreeCAD via python and load the current model again? That would make it a bit easier :)
wmayer
Founder
Posts: 20242
Joined: Thu Feb 19, 2009 10:32 am
Contact:

Re: Reload Workbenches for Development

Post by wmayer »

Code: Select all

import FreeCADGui
from PySide import QtGui,QtCore
args = QtGui.QApplication.arguments()[1:]
if FreeCADGui.getMainWindow().close():
    QtCore.QProcess.startDetached(QtGui.QApplication.applicationFilePath(),args)
This restarts the FreeCAD process with the same arguments it has been started before. If in your running FreeCAD instance you have manually created a new document you want to restore then you must extend the above code snippet. Save the document under a certain file path and add it to args.
Post Reply