1
$\begingroup$

I wan't to make an operator that has button in it that is another operator, that would call some method in original operator.

In the example bellow I want to rename object, after I click on Run. Confusing part is that, although execute_function in MineTestClass is called, nothing happens. And then if I call Execute operator from Search menu, it renames object correctly.

import bpy, bmesh
import mathutils
import os
from mathutils import Vector

bpy.types.Scene.current_operator = None


class MineExecuteOperator(bpy.types.Operator):
    bl_idname = "mine.execute_operator"
    bl_label = "Execute operator"

    def execute(self, context):
        print ("Current Operator: " + str(bpy.types.Scene.current_operator))
        bpy.types.Scene.current_operator.execute_function(context)
        return {'FINISHED'}


class MineTestClass(bpy.types.Operator):
    bl_idname = "mine.test_class"
    bl_label = "Test Class"
    bl_options = {'REGISTER', 'UNDO'}

    new_name = bpy.props.StringProperty()

    def execute_function(self, context):
        obj = bpy.context.selected_objects[0]
        obj.name = self.new_name

    def invoke(self, context, event):
        bpy.types.Scene.current_operator = self
        return {"FINISHED"}


    def draw(self, context):
        layout = self.layout
        box = layout.box()
        box.prop(self, 'new_name', expand=True, text="Name")
        box.operator("mine.execute_operator", text="Run")


def register():
    bpy.utils.register_class(MineExecuteOperator)
    bpy.utils.register_class(MineTestClass)


def unregister():
    bpy.utils.unregister_class(MineExecuteOperator)
    bpy.utils.unregister_class(MineTestClass)
$\endgroup$
1
$\begingroup$

Let me first say I'm not really sure if this is the way to go.

A registered operator (ie options={'REGISTER', 'UNDO'}) keeps its state, that's why calling a method from another appears to have no effect. The registered operator also needs to have an execute method for 'REDO' to work. For example without the flag in code below a registered op will auto rename whenever the new_name field is changed.

A registered operator when run will be context.active_operator and a history of operators is kept in the context.window_manager.operators list.

Here is one take on what you want to do. Rather than calling a method of the original op from the other, it sets a flag, that if set will rename the object. Once again notice how changing a prop of the reg'd operator prompts a call to execute().

import bpy
from bpy.props import StringProperty, BoolProperty

class MineExecuteOperator(bpy.types.Operator):
    bl_idname = "mine.execute_operator"
    bl_label = "Execute operator"

    def execute(self, context):
        print ("Current Operator: " ,context.active_operator)
        context.active_operator.rename = True
        return {'FINISHED'}

class MineTestClass(bpy.types.Operator):
    bl_idname = "mine.test_class"
    bl_label = "Test Class"
    bl_options = {'REGISTER', 'UNDO'}

    new_name = StringProperty()
    # a flag to rename when set.
    rename = BoolProperty(default=False, options={'SKIP_SAVE'})

    def execute_function(self, context):
        obj = context.object
        obj.name = self.new_name

    def invoke(self, context, event):
        # operator invoked
        return {"FINISHED"}

    # without an execute this wont work with REDO
    def execute(self, context):
        print("EXECUTE")
        if self.rename:
            self.execute_function(context)
            self.rename = False
        return {'FINISHED'}

    def draw(self, context):
        layout = self.layout
        box = layout.box()
        box.prop(self, 'new_name', expand=True, text="Name")
        box.operator("mine.execute_operator", text="Run")

def register():
    bpy.utils.register_class(MineExecuteOperator)
    bpy.utils.register_class(MineTestClass)

def unregister():
    bpy.utils.unregister_class(MineExecuteOperator)
    bpy.utils.unregister_class(MineTestClass)

if __name__ == "__main__":
    register()
$\endgroup$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.