Solved Python Xpresso node detect Userdata button press message

Hi there,
I have a Null with userdata and a button in it.
I also have an Xpresso tag and a Python Node that I want it to listen a message from that button. The button ID is 10.
In my research I wasn't able to find any examples for what I need, so I tried this code that I found.
I know this is for Python Generator obj, but I want something similar, and to learn how to detect a button from my userdata and then run an action.

Thanks a lot

import c4d

def message(mid, data):
    if mid is c4d.MSG_DESCRIPTION_COMMAND:
        if not isinstance(data, dict) or "id" not in data:
            raise RuntimeError("Malformed message data.")
        senderDescId = data["id"]
        if senderDescId[0].id == c4d.ID_USERDATA and senderDescId[1].id == 10:
            print ("User data button has been pressed.")
            # then run an action in main() function

def main():
    # waiting for the right message before running anything...

Hey @danielsian,

First, you could not receive core messages in a Python Xpresso node message function even if it would implement it, because the message function in scripting elements is always a thin wrapper around NodeData.Message, i.e., you receive node message there, not core messages. Please refer to the message manual for details about the message system.

Regarding workarounds: There are no direct ones.

In principle, you can implement a MessageData or GeDialog and use their CoreMessage method to fetch the core message you are after and then propagate it as a MSG_BASECONTAINER via C4DAtom.Message to the scripting node of your choice. But this of course requires the scripting element to implement a message function which propagates the ingoing message stream from its C4DAtom.Message to that script module. There is no way around this for you when the scripting element does not implement message.

What you could do is just implement a dialog or message hook which does all the work for you. I.e., you cut out the part where you propagate the message to all relevant nodes, and instead do things yourself.

Both the message propagating workflow and the command and control workflow require you to implement node discovery, i.e., on every EVMSG_CHANGE you must traverse the scene and find all elements which are candidates for your "actions".

edit: In case you misspoke and actually meant atom/node message, then this is not possible at all, because you cannot get access to the message stream of that node.

Cheers,
Ferdinand

MAXON SDK Specialist
developers.maxon.net

Hello @danielsian,

Thank you for reaching out to us. What you are trying to do does not work because the Python Xpresso node does not implement a message method. When unsure about which scripting element supports what, I would recommend having a look at the Python Scripting Nodes section in our documentation. Or in this case specifically the Python Xpresso Node.

Cheers,
Ferdinand

MAXON SDK Specialist
developers.maxon.net

@ferdinand Thanks for you quick response. I've read somewhere while researching about this issue, if I'm not wrong it was even you replying to another query regarding something similar to this, saying that it would be possible to get a core message in the Python Xpresso.
So based on that, is this a possible workaround?

Hey @danielsian,

First, you could not receive core messages in a Python Xpresso node message function even if it would implement it, because the message function in scripting elements is always a thin wrapper around NodeData.Message, i.e., you receive node message there, not core messages. Please refer to the message manual for details about the message system.

Regarding workarounds: There are no direct ones.

In principle, you can implement a MessageData or GeDialog and use their CoreMessage method to fetch the core message you are after and then propagate it as a MSG_BASECONTAINER via C4DAtom.Message to the scripting node of your choice. But this of course requires the scripting element to implement a message function which propagates the ingoing message stream from its C4DAtom.Message to that script module. There is no way around this for you when the scripting element does not implement message.

What you could do is just implement a dialog or message hook which does all the work for you. I.e., you cut out the part where you propagate the message to all relevant nodes, and instead do things yourself.

Both the message propagating workflow and the command and control workflow require you to implement node discovery, i.e., on every EVMSG_CHANGE you must traverse the scene and find all elements which are candidates for your "actions".

edit: In case you misspoke and actually meant atom/node message, then this is not possible at all, because you cannot get access to the message stream of that node.

Cheers,
Ferdinand

MAXON SDK Specialist
developers.maxon.net

@ferdinand Thanks for your comprehensive explanation. I really appreciate that.
Cheers