I am trying to convert my script into an add-on. I have most of the core functionality in place, so I want to try turning it into an operator so that I can connect it to a button.

When I try to test my operator using both the console and the spacebar search menu inside of the Node Editor, it doesn't do anything. However, when I click "Run Script" in the text editor, it runs fine.

This is my source code

Following this tutorial, I notice that he defines 'main' as a function rather than a class. When I do this, running the script does not work, but it works when I run it from the console. Interestingly, when I run the same command from the spacebar menu, Blender hard crashes. Any ideas?


1 Answer 1


When you run the script, the various properties in the script get set and you use them in your functions, this doesn't happen when you invoke the operator. An operator is invoked in a clean environment, you only get properties you setup in the operator. An addon is a python module and allows you to expand that to some degree as the script properties are actually module properties, but you still need to set the properties from the operator or the register() function, not the top level script steps.

From your operator's execute() method you should setup the properties you want to use based on the active selection at that time and not what may have been active at the time the script was run to register the operator. To do this, you should use the context parameter passed into the execute() method instead of using bpy.context, pass the context parameter from your operator to your functions when you call them.

As you mention - you have class main(), by creating an instance in your operator you aren't actually calling any of the methods listed in the class, so yes it should be a function not a class, unless you move the function calls into the class __init__() method or another method that you then call.

While you have worked out the steps you need to use, you just have to reorganise it so that it can be used within blenders operator context.

  • $\begingroup$ I don't think I really understand. What context does it want? Does it want a bl_context tag set to 'NODE_EDITOR' or do I need to pass the context as the active material operator? $\endgroup$
    – Rug
    Aug 28, 2017 at 21:23
  • $\begingroup$ The methods in the operator receive a context parameter, pass that in function calls instead of bpy.context. It is often the same but can be overridden. $\endgroup$
    – sambler
    Aug 29, 2017 at 4:59
  • $\begingroup$ I think the context I have is the active material, right? So do I pass that as an argument to the tunction as 'context' and inside the function use context instead of my material name variable? Or do I make it a global variable and simply stick it in as the argument for all of them? I am very confused on why it is done this way. $\endgroup$
    – Rug
    Aug 31, 2017 at 2:31
  • $\begingroup$ The context parameter passed to an operator is comparable to bpy.context and should be used in it's place. It gives access to the current scene, active object, selected objects... Many times it will be the same as bpy.context but it can be altered for the duration of a script as described in the above link. $\endgroup$
    – sambler
    Aug 31, 2017 at 7:22
  • $\begingroup$ So is the context parameter used as a convenience variable, like C for bpy.context in the console? Take for instance, my mat variable. That is a convenience variable that takes the active material using bpy.context.active_object.active_material.name. Should I be using context as the variable I am using when calling parameters instead of mat? Or is context just something I throw in as a global, like context = bpy.context and then put it as a parameter for my functions? $\endgroup$
    – Rug
    Aug 31, 2017 at 17:44

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .