C4D GUI Python Callback



  • Hi Folks,

    We trying to call a python script from the menu bar.

    From in this example
    https://developers.maxon.net/docs/Cinema4DPythonSDK/html/misc/pluginstructure.html?highlight=pluginmessage#PluginMessage
    a python script can be attached to a container via

    menu.InsData(c4d.MENURESOURCE_COMMAND, "IDM_NEU")*

    To attach an external python script to a button of the menu I needs to be registered as a plugin
    with a unique plugin ID (e.G. 123456)

    menu.InsData(c4d.MENURESOURCE_COMMAND, "PLUGIN_CMD_123456")

    Does this mean for each button added to the menu bar, you have to register a new plugin with a unique ID in order to attach a callback to it ?
    Or is there a more convenient way of doing this ?

    *e.G. menu.InsData(c4d.MENURESOURCE_COMMAND, callbackFunction(args))

    Thank for your help



  • Hi and welcome to the new Plugin Cafe!

    It is not possible to pass a Python function for MENURESOURCE_COMMAND. Only a Cinema 4D command resource ID ("IDM_NEU") or a plugin command ID ("PLUGIN_CMD_123456") can be given.

    A CommandData plugin can have sub-ID commands returned from GetSubContainer(). The sub-ID commands are then invoked with ExecuteSubID().
    But there's a limitation with this currently. At least two CommandData have to be registered from the same plugin for the sub-commands to be taken into account.

    Please read and use How to Post Questions and Q&A New Functionality. This time I added tags and turned the thread into a Q&A.



  • Hey,

    thank you for the reply.
    I managed to implement the GetSubContainer() and ExecuteSubID() function.

    However what I don’t get to work is;
    How you would you specify the displayed names of the commands ?

    Before when registering multiple commands, the name was specified in the same step
    e.G.

    c4d.plugins.RegisterCommandPlugin(id=“PLUGIN_CMD_123456”, str=‘New Command’, info=0, icon=None, help="", dat=self.__callBackInstance)
    

    From the docs the CommandData.GetSubContainer() looks like the BaseContainer.SetString(id, s) function would do something like that.

    bc = BaseContainer()
    bc.SetString(1, "Submenu Test")
    bc.SetString(1000, "First Entry")
    submenu.InsData(0, bc)
    

    But I am not entirely sure.
    What would be the correct way to pass the command to the container and specify their names ?

    thanks in advance
    and get busy cafe :)



  • Hi,

    A string with format "PLUGIN_CMD_123456" is meant to be used with MENURESOURCE_COMMAND, not RegisterCommandPlugin().
    It tells Cinema the command ID and name for the menu item to be added.
    Note the sub-IDs returned from GetSubContainer() are specific to a command and aren't global to Cinema.

    Maybe CommandData isn't what you really need. Scripts from the user folder are automatically loaded and can be added to any menu using Customize Menus dialog.