Community
Fusion API and Scripts
Got a new add-in to share? Need something specialized to be scripted? Ask questions or share what you’ve discovered with the community.
cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 

Command handling setup - missing CommandEventArgs Object

4 REPLIES 4
SOLVED
Reply
Message 1 of 5
kealan4LBW
150 Views, 4 Replies

Command handling setup - missing CommandEventArgs Object

Hi, 

I'm trying to call a command execute from a different event.py script but I'm struggling to get my head around the way the event handler objects and events are set up in the add-in examples. 

 

Code below from the API examples:

From my very limited understanding, when the command_created() function is called by the initialisation function , it then in turn calls the futil.add_handler function, which creates a link between the  tigger event, which is the command.execute event of a adsk.core.CommandCreatedEventArgs object which the initialisation function created via yet another handler, and the resulting function that gets called, command_exectute()

 

 

def command_created(args: adsk.core.CommandCreatedEventArgs):
    # General logging for debug.
    futil.log(f'{CMD_NAME} Prompt user for product ID')

    # https://help.autodesk.com/view/fusion360/ENU/?contextId=CommandInputs
    inputs = args.command.commandInputs

    # TODO Define the dialog for your command by adding different inputs to the command.

    # Create a simple text box input.
    inputs.addTextBoxCommandInput('text_box', 'Some Text', 'Enter some text.', 1, False)

    # Create a value input field and set the default using 1 unit of the default length unit.
    defaultLengthUnits = app.activeProduct.unitsManager.defaultLengthUnits
    default_value = adsk.core.ValueInput.createByString('1')
    inputs.addValueInput('value_input', 'Some Value', defaultLengthUnits, default_value)

    # TODO Connect to the events that are needed by this command.
    futil.add_handler(args.command.execute, command_execute, local_handlers=local_handlers)
    futil.add_handler(args.command.inputChanged, command_input_changed, local_handlers=local_handlers)
    futil.add_handler(args.command.executePreview, command_preview, local_handlers=local_handlers)
    futil.add_handler(args.command.validateInputs, command_validate_input, local_handlers=local_handlers)
    futil.add_handler(args.command.destroy, command_destroy, local_handlers=local_handlers)

 

 



Then going into the add handler function to see what the handler looks like: 

 

 

def add_handler(
        event: adsk.core.Event,
        callback: Callable,
        *,
        name: str = None,
        local_handlers: list = None
):
    """Adds an event handler to the specified event.

    Arguments:
    event -- The event object you want to connect a handler to.
    callback -- The function that will handle the event.
    name -- A name to use in logging errors associated with this event.
            Otherwise the name of the event object is used. This argument
            must be specified by its keyword.
    local_handlers -- A list of handlers you manage that is used to maintain
                      a reference to the handlers so they aren't released.
                      This argument must be specified by its keyword. If not
                      specified the handler is added to a global list and can
                      be cleared using the clear_handlers function. You may want
                      to maintain your own handler list so it can be managed 
                      independently for each command.

    :returns:
        The event handler that was created.  You don't often need this reference, but it can be useful in some cases.
    """   
    module = sys.modules[event.__module__]
    handler_type = module.__dict__[event.add.__annotations__['handler']]
    handler = _create_handler(handler_type, callback, event, name, local_handlers)
    event.add(handler)
    return handler




def _create_handler(
        handler_type,
        callback: Callable,
        event: adsk.core.Event,
        name: str = None,
        local_handlers: list = None
):
    handler = _define_handler(handler_type, callback, name)()
    (local_handlers if local_handlers is not None else _handlers).append(handler)
    return handler

 



And then the actual execute function definition, which needs to be passed a CommandEventArgs object so it can use the object to collect the inputs from the dialog boxes using the .command.commandInputs properties, presumably. 

 

def command_execute(args: adsk.core.CommandEventArgs):
    # General logging for debug.
    futil.log(f'{CMD_NAME} Command Execute Event')

    # TODO ******************************** Your code here ********************************

    # Get a reference to your command's inputs.
    inputs = args.command.commandInputs
    text_box: adsk.core.TextBoxCommandInput = inputs.itemById('text_box')
    value_input: adsk.core.ValueCommandInput = inputs.itemById('value_input')

    # Do something interesting
    text = text_box.text
    expression = value_input.expression
    msg = f'Your text: {text}<br>Your value: {expression}'
    ui.messageBox(msg)

 

 

My problem is when I try to call this command_exectute function from another function in another script, I don't know what CommandEventArgs object to pass to it, if I pass it nothing, I get an error about missing args. I've managed to pass it the CommandEventArgs class instead of an instance of the class, which also didn't work. 


I can't see where the event handler is creating the instance of the CommandEventArgs object, or passing any object to the execute function. 


Do I create a new commandeventargs object in my other py script and pass that do the execute function or do I need to find a pointer to the object that the event handler made and pass  it that instead, or does it matter? 


I'm struggling to wrap my head around how this is working. 



4 REPLIES 4
Message 2 of 5
kandennti
in reply to: kealan4LBW

Hi @kealan4LBW -San.

 

Isn't it difficult because you are trying to call the command_exectute function from another script?

Wouldn't it be better to put what you are currently doing in the command_execute function in a separate file and call it from two different scripts?

Message 3 of 5
kealan4LBW
in reply to: kandennti

That c9mmand execute function is straight out of the API example docs, I haven't changed it, all I'm trying to do now is call the function to make the box appear but I can't even get that to work 

Message 4 of 5
BrianEkins
in reply to: kealan4LBW

You execute a command by getting the CommandDefinition of your command and calling the execute method. This results in Fusion firing the commandCreated event. You get a CommandDefinition by using the UserInterface.commandDefinitions.itemById. When you create your command, usually using the CommandDefinitions.addButtonDefinition method, you provide the ID for your command. That's the ID, you'll use in itemById.

---------------------------------------------------------------
Brian Ekins
Inventor and Fusion 360 API Expert
Website/Blog: https://EkinsSolutions.com
Message 5 of 5
kealan4LBW
in reply to: kealan4LBW

It works! Thank you Brian. 

The commandDialog example has this command definition: 

cmd_def = ui.commandDefinitions.addButtonDefinition(CMD_ID, CMD_NAME, CMD_Description, ICON_FOLDER)

 

And then from my second script, I've got an import of the example py file and just called 

from .. import commandDialog


commandDialog.cmd_def.execute()


and its firing the event and displaying 🙂 

 

Can't find what you're looking for? Ask the community or share your knowledge.

Post to forums  

Autodesk DevCon in Munich May 28-29th


Autodesk Design & Make Report