1
$\begingroup$

I am updating the active object's location.x with a FloatProperty with the following code.

How can I change the value of the FloatProperty slider to the active_object's current location.x when the active_object changes?

Thank you!

import bpy

class SomePanel( bpy.types.Panel ):
    bl_label = "Property panel"
    bl_space_type = "VIEW_3D"
    bl_region_type = "UI"

    def draw(self, context):
        layout = self.layout
        scn = context.scene
        layout.prop( scn, 'someValue' )

def whenUpdate( self, context ):
    if context.active_object:
        context.active_object.location.x = self.someValue
    print( 'update', self.someValue )

def register():
    bpy.types.Scene.someValue = bpy.props.FloatProperty( 
        name = "Float", 
        description = "Enter a float", min = -100, max = 100,
        update = whenUpdate ) #Assign the update function here
    bpy.utils.register_class(SomePanel)

def unregister():
    bpy.utils.unregister_class(SomePanel)
    del bpy.types.Scene.someValue

if __name__ == "__main__":
    register()
$\endgroup$
2
  • $\begingroup$ Hello ! Just a thought, wouldn't it be easier to define a property with a getter that fetches the active object's x location value ? $\endgroup$
    – Gorgious
    Dec 6, 2021 at 8:14
  • $\begingroup$ Hello @Gorgious, thank you for the reply. It might be easier! Do you mean a PropertyGroup class? If so, can I access the scene's someValue variable and the active_object from there? $\endgroup$ Dec 6, 2021 at 8:49

2 Answers 2

1
$\begingroup$

If I understood the problem correctly, you can use Getter / Setter functions to achieve your goal.

import bpy

def get_value(self):
    return bpy.context.active_object.location.x

def set_value(self, value):
    bpy.context.active_object.location.x = value

if __name__ == "__main__":
    bpy.types.Scene.someValue = bpy.props.FloatProperty(get=get_value, set=set_value)

enter image description here

Of course you'll have to add safeguards so you don't try to run the functions if there is no active object.

$\endgroup$
1
  • $\begingroup$ This is perfect, thank you!! $\endgroup$ Dec 6, 2021 at 9:00
0
$\begingroup$

I've found an answer via from Detective bpy on the Blender Community Discord. They provided a link to this post: https://blender.stackexchange.com/a/239606

Which led me to this solution:

import bpy

def msgbus_callback(*arg):
    bpy.context.scene.someValue = bpy.context.selected_objects[0].location.x
        
def subscribe_to_obj(): 
    bpy.msgbus.subscribe_rna(
        key=(bpy.types.LayerObjects, 'active'),
        owner=bpy,
        args=('something, if you need',),
        notify=msgbus_callback
        )

class VIEW3D_PT_SomePanel( bpy.types.Panel ):
    bl_label = "Property panel"
    bl_space_type = "VIEW_3D"
    bl_region_type = "UI"

    def draw(self, context):
        layout = self.layout
        scn = context.scene
        layout.prop( scn, 'someValue' )

def whenUpdate( self, context ):
    if context.active_object:
        context.active_object.location.x = self.someValue
    print( 'update', self.someValue )

def register():
    bpy.types.Scene.someValue = bpy.props.FloatProperty( 
        name = "Float", 
        description = "Enter a float", min = -100, max = 100,
        update = whenUpdate ) #Assign the update function here
    bpy.utils.register_class(VIEW3D_PT_SomePanel)
    subscribe_to_obj()

def unregister():
    bpy.utils.unregister_class(VIEW3D_PT_SomePanel)
    del bpy.types.Scene.someValue

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

You must log in to answer this question.

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