using user data buttons in python [SOLVED]

On 15/08/2015 at 04:47, xxxxxxxx wrote:

hi guys

i want to run some code upon the pressing of a button in user data, but i can't figure out how..

i've already read this discussion:
but i don't fully understand it

for example, i think that this code (from the discussion above) is meant to be used in an interaction tag:

def message(id, data) :
    if id == 18: # Don't know why 18 yet :(
        for i in data['msg']: #seems to be the consistently changing thing
            print i[c4d.DESC_NAME] #the number stays [c]( aligning with different button presses

but if i blindly put this in the interaction tag nothing happens in the console upon the pressing of a user data button

i'm obviously missing something, i don't even understand what's a placeholder in that code an what is not

can somebody help?

On 17/08/2015 at 08:45, xxxxxxxx wrote:


welcome to the PluginCafé forums :slightly_smiling_face:
Actually the information is already in the thread you linked above. But I agree, it's not at all obvious. By the way, it's perfectly fine to revive old threads, as long as you stay on topic.

First note, that in the Manage User Data dialog, for each User Data parameter, there's an ID displayed (under Properties, right below "Short Name"). This is the ID to be used to differentiate between different User Data entries.

Now, here's how to use a User Data button in the interaction tag (example assumes, there are only two UserData buttons with User Data IDs one and two) :

def message(id, data) :
    #Code for what happens when the tag gets a message goes here
    if id == c4d.MSG_DESCRIPTION_COMMAND: # MSG_DESCRIPTION_COMMAND is the magic 18, mentioned in the other thread
        id2 = data['id'][0].id
        if id2 == c4d.ID_USERDATA:
            userDataId = data['id'][1].id
            if userDataId == 1:
                print "Button 1 pressed"
            elif userDataId == 2:
                print "Button 2 pressed"

On 17/08/2015 at 11:26, xxxxxxxx wrote:

Thank you for info!
Needs to duplicate it in c4d manual or alternative methods(callbutton or something like)  in pyAPI

On 20/08/2015 at 12:50, xxxxxxxx wrote:

Originally posted by xxxxxxxx

By the way, it's perfectly fine to revive old threads, as long as you stay on topic.

oh ok, i'll keep that in mind thanks

i'm still missing something..
this is what i think i've understood so far:

some actions in cinema send a message. this message has two variables, id and data (not sure what
"this message has two variables" mean..i still don't fully understand what a message is).

when i press a button, the id is c4d.MSG_DESCRIPTION_COMMAND (or 18) and data..what is data exactly?

so in your code first you check whether the message was sent by a button, then you extract some kind
of information from the variable data (is id = data['id'][0].id something that has to do more with
python or with the c4d module? i'm not familar with this syntax). not sure why you assign this vale to
id though.

the information you extract from data is an integer that in our case has the value c4d.ID_USERDATA (or 700).
i use this value when i want to access a user data, for example obj[c4d.ID_USERDATA,1] gives me the
value stored in obj's user data with ID 1, so i guess that the line if id == c4d.ID_USERDATA tells you
that the message was coming from a user data (or something similar).
then the next information you extact from the variable data tells you the user data ID.

ok so, even if i don't understand precisely every step, i have a blurry idea of what the code does.
the problem is, this code still doesn't work for me for some reason..

i create a cube (or whatever), i add two user data buttons with ID 1 and 2, i copy the code in the
interaction tag, and i check the console upon the pressing of the buttons..still nothing happens,
no "Button 1 pressed" or Button 2 pressed..what am i missing?

thanks again for your reply

On 21/08/2015 at 02:58, xxxxxxxx wrote:


a Message() is nothing but a function call to a certain entity (objects, materials, tags,...), in order to notify it of some change. There are a lot of different messages, differentiated by their type/ID. Each message can provide data, which in the C++ API comes in a special structure. Often this structure then also contains a BaseContainer with further information. Depending on the type of a message, the structure and content of such a BaseContainer differ.
Now, in Python, the structure is mapped into a dictionary. That's the strange syntax (data['id']), which simply returns the value for the keyword "id" from the data dictionary.

Here the ID/type of the message we are looking for is c4d.MSG_DESCRIPTION_COMMAND. It's mainly used for button presses (but not restricted to these).

Then normally (I mean, in a standard description of for example an object) data['id'][0].id contains the ID of the description parameter (which could already be your button). But with User Data it's a tiny bit more complicated. As you get the c4d.ID_USERDATA here, which tells you, that you get the MSG_DESCRIPTION_COMMAND for a User Data parameter. I'm sorry, I assigned this to id in my first example (it's already corrected), it was a mistake (even though no bug). Didn't want to confuse you.

So for User Data you need to go one level deeper, in order to also find out the actual User Data ID (with data['id'][1].id).

And now, finally, why it is not working in your case:
As said in the beginning a message is sent to an object or tag. But it is no broadcast, it is send directly to one entity. You create User Data on a cube and have a script on an interaction tag. That won't work.
The solution would be to have the buttons on the the Interaction tag (which I assumed, when writing my first answer in this thread).

On 21/08/2015 at 04:21, xxxxxxxx wrote:

thank you very very much for the detailed explaination, it's much clearer now

On 21/08/2015 at 04:33, xxxxxxxx wrote:

You are welcome.
Actually I forgot to provide the link, as it is actually documented in the Python SDK Docs:

Edit: Updated link

On 15/09/2015 at 02:17, xxxxxxxx wrote:


I'm trying this example out, but I can't get it to work :s
Getting inside the message is no problem, but as soon as I check if it's a command, my code fails, I guess.

It's inside a python tag, and my button is on the tag and on the object as well (for testing purposes).

Here is my code:

def message(id, data) :  
  print "Inside Message"  
      print "Clicked"  

"Inside Message" gets printed everytime I click, yet "Clicked" never gets printed.

Does anybody have an idea what could be the problem here?

Thanks in advance for your help and time!

On 15/09/2015 at 03:45, xxxxxxxx wrote:


Well, apparently, my data is empty, so the id becomes MSG_MULTI_MARKMATERIALS.

"When data is None this is sent to plugin nodes to let them mark the materials that they use. Otherwise the message is sent to let you translate you material links, for example when a material is replaced, and then the corresponding structure is MarkMaterials. (An example for both cases is included on the MarkMaterials page.)"

On 15/09/2015 at 05:19, xxxxxxxx wrote:


So, it's only possible to use this in the interaction tag?
No way at all for doing it inside a python tag?

Thanks for your help and time!

On 15/09/2015 at 09:36, xxxxxxxx wrote:

Hi Casimir,

no, the Python Tag currently does not support UserData buttons. Sorry.

On 15/09/2015 at 10:02, xxxxxxxx wrote:

Hi Andreas,

Okay, thanks for your answer!

I'll just hide some of the properties of the interaction tag (shown in the object), then.

On 02/11/2015 at 10:56, xxxxxxxx wrote:


please forgive my stupidity. While the Python tag does indeed not support the standard way of processing buttons, Cairyn came up with a nice solution for the Python tag in this thread about Rename by adding a digit at the end. He makes use of MSG_DESCRIPTION_CHECKUPDATE, which works really nice. Sorry, I didn't come up with that solution earlier.

On 03/11/2015 at 01:21, xxxxxxxx wrote:

Hi Andreas,

Thanks for the information!!

And no problem, you have a lot to think about :p