My script runs but not the button in the N panel

Hi all,

I have a script that it works if I hit the Run Script button, sadly that’s not the case with the button that I added in the N panel.
Can anyone could give me a hint on why this is happening?
Another problem is that I had to comment the #return {‘FINISHED’} since it gives me execution problems.

Here is the code, I have gathered some lines from internet:

import bpy
from mathutils import Matrix, Vector

class OriginToBackLeftOperator(bpy.types.Operator):
    bl_idname = "object.move_originbackleft_operator"
    bl_label = "Back Left"
    bl_options = {'REGISTER', 'UNDO'}

    def origin_to_bottom(ob, matrix=Matrix()):
        me = ob.data
        mw = ob.matrix_world
        local_verts = [matrix @ Vector(v[:]) for v in ob.bound_box]
        o = sum(local_verts, Vector()) / 8
        o.z = min(v.z for v in local_verts)
        o = matrix.inverted() @ o
        me.transform(Matrix.Translation(-o))

        mw.translation = mw @ o

    for o in bpy.context.scene.objects:
        if o.type == 'MESH':
            origin_to_bottom(o)
    #return {'FINISHED'}

#------UI------#
class TestPanel(bpy.types.Panel):
    """Creates a Panel in the Object properties window"""
    bl_label = "UKI Panel"
    bl_idname = "VIEW_PT_test"
    bl_space_type = 'VIEW_3D'
    bl_region_type = 'UI'
    bl_category = "TEST TAB"

    def draw(self, context):
        layout = self.layout

        row = layout.row()
        row.operator("object.move_originbackleft_operator")
        
def register():
    bpy.utils.register_class(OriginToBackLeftOperator)
    bpy.utils.register_class(TestPanel)


def unregister():
    bpy.utils.unregister_class(OriginToBackLeftOperator)
    bpy.utils.unregister_class(TestPanel)


if __name__ == "__main__":
    register()

Thanks in advance,
Juan

Hi,
the "return {‘FINISHED’} have to be in an execute function like this example from the API : (https://docs.blender.org/api/current/info_quickstart.html)

def main(context):
    for ob in context.scene.objects:
        print(ob)

class SimpleOperator(bpy.types.Operator):
    """Tooltip"""
    bl_idname = "object.simple_operator"
    bl_label = "Simple Object Operator"

    @classmethod
    def poll(cls, context):
        return context.active_object is not None

    def execute(self, context):
        main(context)
        return {'FINISHED'}

I’m not sure it’s a good idea to have a recursive function inside an operator.

1 Like

Thank you, that pointed me in the right direction, now I got it working in the Button.

Just a small tip, watch out for the indentation, unlike other programming languages, its kinda important in python.