1
$\begingroup$

I would like to change the text on a button that locks the Camera to View Window. When it is locked I would like it to say Unlock Camera and when it is unlocked I would like it so say Lock Camera.

Here is my code which is not working...

Operator Code

class ADD_OT_nms_lockcamera(bpy.types.Operator):
    bl_idname = 'add.nms_lockcamera'
    bl_description = 'Lock Cam to View'
    bl_category = 'NMS'
    bl_label = 'Lock to view'

    
    def execute(self, context):
        obj_camera = bpy.context.scene.camera
        for area in bpy.context.screen.areas:
           if area.type == 'VIEW_3D':
              for space in area.spaces:
                 if space.type == 'VIEW_3D':
                    if space.lock_camera == False:
                        space.lock_camera = True
                        button_name=obj_camera.name +" Locked"
                        print(button_name)
                    else:
                        space.lock_camera = False
                        button_name= obj_camera.name +" Unlocked"
                        print(button_name)
        return {"FINISHED"}  

Panel code

...
 layout.separator()
        layout.label(text="Lock Cam to View")
        layout.operator("add.nms_lockcamera", text=button_name)

I get the error NameError: name 'button_name' is not defined I have tried trapping with try:... except NameError: but with no success

$\endgroup$
0

1 Answer 1

2
$\begingroup$

In short: the panel doesn´t know button_name

An variable belongs to its class (instance attribute) and won´t affect other classes. The reason why a attribute name can be assigned more than once - in different classes. The change is made in the operator class. The new value must be returned to the panel.

Two possibilities:

A) The standard way is to use a property. The operator changes the property. The panel gets the new value from property when redrawn by mouseover.

B) A class attribute in the operator and change the meta object with __class__ for the panel.

https://stackoverflow.com/questions/7374748/whats-the-difference-between-a-python-property-and-attribute

https://www.pythontutorial.net/python-oop/python-class-attributes/

https://stackoverflow.com/questions/8060751/what-in-the-world-is-the-attribute-class-in-python

import bpy

### UI                      
class TESTPANEL_PT_Main(bpy.types.Panel):
    bl_idname = 'TEST_PANEL_PT_main'
    bl_label = "Test Panel"                      
    bl_space_type = 'VIEW_3D'
    bl_region_type = 'UI'
    bl_category = "TEST"
    def draw(self, context):
        layout = self.layout
        layout.separator()
        layout.label(text="Lock Cam to View")

        # A) with property
        layout.operator("add.nms_lockcamera", text= context.scene.my_props.camera) # text = propertyClass.property)    

        # B) with class attribute
        layout.operator("add.nms_lockcamera", text= ADD_OT_nms_lockcamera.camera)  # text = operatorClass.attribute 
        


### OPERATOR
class ADD_OT_nms_lockcamera(bpy.types.Operator):
    bl_idname = 'add.nms_lockcamera'
    bl_description = 'Lock Cam to View'
    bl_category = 'NMS'
    bl_label = 'Lock to view'

    camera = ""   # B) class attribute
    
    def execute(self, context):
        obj_camera = bpy.context.scene.camera
        for area in bpy.context.screen.areas:
           if area.type == 'VIEW_3D':
              for space in area.spaces:
                 if space.type == 'VIEW_3D':
                    if space.lock_camera == False:
                        space.lock_camera = True
                        button_name=obj_camera.name +" Locked"
                        print(button_name)
                    else:
                        space.lock_camera = False
                        button_name= obj_camera.name +" Unlocked"
                        print(button_name)

        # A) change property in propertyClass
        context.scene.my_props.camera = button_name

        # B) change meta-class object for referenced panel
        self.__class__.camera = button_name 

        return {"FINISHED"}  



### PROPERTIES
class TestProperties(bpy.types.PropertyGroup):
    camera : bpy.props.StringProperty(default = "ggg")  # A) property



### REGISTRY
classes = (
    TESTPANEL_PT_Main, 
    ADD_OT_nms_lockcamera,
    TestProperties,  
    )

def register():
    from bpy.utils import register_class
    for cls in classes:
        register_class(cls)
    bpy.types.Scene.my_props = bpy.props.PointerProperty(type = TestProperties)            


def unregister():
    from bpy.utils import unregister_class
    for cls in reversed(classes):
        unregister_class(cls)
    bpy.types.Scene.my_props

if __name__ == "__main__":
    register()
$\endgroup$
1
  • $\begingroup$ Perfect thanks so much. i didn't understand the scope in Python. I used the property method and all is great $\endgroup$
    – Nick Wild
    Nov 10, 2022 at 10:52

You must log in to answer this question.

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