Jump to content
Ultimaker Community of 3D Printing Experts

Plugin with 2 stages


Recommended Posts

Posted (edited) · Plugin with 2 stages

I'm making a (very simple) Finite Elements Analysis plugin where the user can A) Assign loads to the body,  and B) Visualize the results on a new coloured mesh. I guessed the best way to present these would be in two tabs AKA stages.


In the plugin's __init__.py I have this:

def getMetaData():
    return {
        #Add 2 new tabs (AKA Stages).
        #When adding 1 stage, the "stage" key holds a dictionary.
        #To add 2 stages, the "stage" key holds a list of dictionaries.
        "stage": [
                "name": i18n_catalog.i18nc("@item:inmenu", "FEM_STAGE1"),
                "weight": 15
                "name": i18n_catalog.i18nc("@item:inmenu", "FEM_STAGE2"),
                "weight": 16
        "tool": ...
def register(app):
      return {
        "stage": [FEMPluginStage1.FEMPluginStage1(),


I saw another plugin that added multiple tools by returning a list of dictionaries, so I guessed the same would apply for adding multiple stages.

Sadly I get this error on boot:


Traceback (most recent call last):
  File "X:\4.7-exe\build\inst\lib\python3.5\site-packages\UM\Qt\Bindings\StageModel.py", line 24, in __init__
  File "X:\4.7-exe\build\inst\lib\python3.5\site-packages\UM\Qt\Bindings\StageModel.py", line 42, in _onStagesChanged
AttributeError: 'list' object has no attribute 'get'


Lurking in Uranium's source code, it looks that _onStagesChanged() has no support for what I'm doing (as it doesn't work on lists of dictionaries).


Is there some way I can do this or is it simply not supported? Thanks

Edited by Tyronnosaurus
better indentation
  • Link to post
    Share on other sites

    Posted · Plugin with 2 stages

    As far as I know, a plugin can define only a single tool and a single stage.


    23 hours ago, Tyronnosaurus said:

    I saw another plugin that added multiple tools

    What other plugin was that?

  • Link to post
    Share on other sites

    Posted · Plugin with 2 stages

    Smart Slice. It defines 2 tools here. You can see some demos in their website.


    In any case, it looks like setting up 2 stages is not an option. For whoever ends up here in the future with the same question, here's the alternative approach I've implemented:


    I've added a QML switch to select between two modes. When toggled, I fetch all SceneNodes in the scene and show/hide the appropriate ones using setVisible() and setEnabled(). It seems to work for now, but there are still some issues (e.g. SceneNodes remain hidden when changing back to Prepare stage).





  • Link to post
    Share on other sites

    Posted · Plugin with 2 stages

    What you need is a single stage with multiple views. That is also what the preview stage does; It basicly provides a way to switch between the views provided by plugins.

    So i'd use the "Show setup" and "Show results" to switch between two views. Since the view gets set back to default when you go to another stage, you also don't need to worry about hiding / showing what you were doing. If you do want that, you can also capture the "Event.ViewActivateEvent" and "Event.ViewDeactivateEvent" in the event loop of the view.

    • Like 1
    Link to post
    Share on other sites

    Posted · Plugin with 2 stages

    Hello again. In my plugin's init, in both getMetaData() and register(),  I've used the method of using a list of dictionaries rather than a single dictionary to add my 2 views.


    The plugin loads correctly, but during boot I get the console error "NameOfPlugin was already added to view list. Unable to add it again". Afterwards, if I use getAllViews() it confirms that only the first view was added.


    Is there a correct way to add 2 views with a single plugin? And if so, how do I refer to them, seeing as they're addressed by the id of the Plugin that added them rather than their own name?

  • Link to post
    Share on other sites

    Posted (edited) · Plugin with 2 stages

    I'll have a look. It could be that I just assumed that adding two views is currently possible. If it's not, we might need to change that.


    I think I found it. You need to set the self._name of the view. If you don't set the name it will use the id of the plugin. If a name is set it will use pluginId_name as the identifier of the view.

    Edited by nallath
    • Like 2
    Link to post
    Share on other sites

    Posted · Plugin with 2 stages

    Works perfectly now. Thank you nallath. For anyone with the same problem, here's the actual code:


    Inside my view's __init__():

    self._name = "MyViewName"

    And to call the view:

    controller = CuraApplication.getInstance().getController()


    • Like 1
    Link to post
    Share on other sites

    Create an account or sign in to comment

    You need to be a member in order to leave a comment

    Create an account

    Sign up for a new account in our community. It's easy!

    Register a new account

    Sign in

    Already have an account? Sign in here.

    Sign In Now

    • Our picks

      • New here? Get ahead with a free onboarding course
        Often getting started is the most difficult part of any process. A good start sets you up for success and saves you time and energy that could be spent elsewhere. That is why we have a onboarding course ready for
        Ultimaker S5 Pro Bundle, Ultimaker S5, Ultimaker S3 Ultimaker 2+ Connect.   
        They're ready for you on the Ultimaker Academy platform. All you need to do to gain access is to register your product to gain free access. 
        Ready? Register your product here in just 60 seconds.
          • Like
        • 14 replies
    • Create New...