# Is it possible to drive other properties in realtime with a single float or int property button without using drivers?

Say I want yo have a float property in the 3DView Toolbar (T), and make it update in realtime several properties in the selected object without using drivers. For example, the "scale" of an object, its an array of 3 values, but I don't want the UI to display its three values, because I want to use only one float slider to drive the three at once (with the intention to preserve the proportion). Even more, think that this could be very useful if I want to drive any kind of values together with just a single slider, not only the scale's array. I spent several days investigating and trying to achieve that, but I finally understood that Panels and Operators are instances of well defined classes which draw functions remain separated, and I can't just make a call from a Panel to a property defined inside an Operator (I use the operator because I want it to update the object in realtime).

Here's a very simple example, just to illustrate the point (I didn't include an Operator here). Note that the script only changes the object's size when the script is rerun.

import bpy

bpy.types.WindowManager.float = bpy.props.FloatProperty(name="Object's Scale", default=1.0)

class OBPanel(bpy.types.Panel):
bl_label = "Selected Object"
bl_idname = "selected_object"
bl_space_type = 'VIEW_3D'
bl_region_type = 'TOOLS'
bl_category = "Tools"
bl_context = "objectmode"

def draw(self, context):
wm = context.window_manager
layout = self.layout
layout.row().prop(wm, 'float')

wm = bpy.context.window_manager
bpy.context.object.scale = wm.float, wm.float, wm.float

def register():
bpy.utils.register_module(__name__)

def unregister():
bpy.utils.unregister_module(__name__)

if __name__ == "__main__":
register()

• scale = wm.float, wm.float, wm.float should be inside the update function – Chebhou May 13 '16 at 10:03
• Finally! I get realtime updates! I love this technique. Thank you. – Chaos May 13 '16 at 10:06
• Best to add your own answer, that shows the working example, to help others. – ideasman42 May 13 '16 at 10:11

Yes, this is possible, it can be done 2 ways.

• Using a property set or update callback.
This lets you either use your property as a way to access other data (by having get & set callbacks, you could for example, keep your property outside of the blend file even).
With an update function you can use this property to control others.
See https://www.blender.org/api/blender_python_api_current/bpy.props.html#get-set-example
• Using drivers, although these need to be setup in the file each time and probably not what you're after.

FINAL UPDATE:

I added the update function and this code works as I wanted. Cheers!

import bpy

def update_func(self, context):
wm = context.window_manager
context.object.scale = wm.float, wm.float, wm.float

bpy.types.WindowManager.float = bpy.props.FloatProperty(
update=update_func,
name="Object's Scale",
default=1.0,
)

class OBPanel(bpy.types.Panel):
bl_label = "Selected Object"
bl_idname = "selected_object"
bl_space_type = 'VIEW_3D'
bl_region_type = 'TOOLS'
bl_category = "Tools"
bl_context = "objectmode"

def draw(self, context):
wm = context.window_manager
layout = self.layout
layout.row().prop(wm, 'float')

def register():
bpy.utils.register_module(__name__)

def unregister():
bpy.utils.unregister_module(__name__)

if __name__ == "__main__":
register()

• Note, using active object in an update function isn't great practice. Ideally you'd add a property on the object which modified other object properties. – ideasman42 May 13 '16 at 10:24