Reload Workbenches for Development

Here's the place for discussion related to coding in FreeCAD, C++ or Python. Design, interfaces and structures.
usbhub
Posts: 280
Joined: Tue Apr 02, 2019 8:22 pm
Location: Earth

Reload Workbenches for Development

Postby usbhub » Tue Mar 03, 2020 5:23 pm

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
Site Admin
Posts: 15756
Joined: Thu Feb 19, 2009 10:32 am

Re: Reload Workbenches for Development

Postby wmayer » Tue Mar 03, 2020 6:18 pm

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
Posts: 24414
Joined: Tue Mar 17, 2015 9:14 am

Re: Reload Workbenches for Development

Postby chrisb » Tue Mar 03, 2020 6:18 pm

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)
User avatar
Kunda1
Posts: 7361
Joined: Thu Jan 05, 2017 9:03 pm

Re: Reload Workbenches for Development

Postby Kunda1 » Tue Mar 03, 2020 6:50 pm

Is this documented somewhere?
Want to contribute back to FC? Checkout:
#lowhangingfruit | Use the Source, Luke. | How to Help FreeCAD | How to report FC bugs and features
vocx
Posts: 4081
Joined: Thu Oct 18, 2018 9:18 pm

Re: Reload Workbenches for Development

Postby vocx » Tue Mar 03, 2020 7:05 pm

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.
To support the documentation effort, and code development, your donation is appreciated: paypal.
usbhub
Posts: 280
Joined: Tue Apr 02, 2019 8:22 pm
Location: Earth

Re: Reload Workbenches for Development

Postby usbhub » Thu Mar 05, 2020 7:31 pm

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

Postby usbhub » Sat Mar 21, 2020 6:37 pm

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
Posts: 7600
Joined: Fri Aug 29, 2014 12:45 am
Location: Saint-Petersburg, Russia

Re: Reload Workbenches for Development

Postby DeepSOIC » 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.
usbhub
Posts: 280
Joined: Tue Apr 02, 2019 8:22 pm
Location: Earth

Re: Reload Workbenches for Development

Postby usbhub » Mon Mar 23, 2020 7:04 pm

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
Site Admin
Posts: 15756
Joined: Thu Feb 19, 2009 10:32 am

Re: Reload Workbenches for Development

Postby wmayer » Mon Mar 23, 2020 8:14 pm

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.