Hi, how do I read a Panel slider value realtime, i.e. I want to update some property as the user is changing the slider in order to give feedback. Can I tap into some sort of event loot somewhere?
The easiest way to get realtime results for a slider is to put the property in an operator.
add_mesh_torus in the script/ops folder of your blender install is a good example of this.
Does that help?
I know that, in the case I stated, the sliders show up in the tool panels that shows up when you hit “t” after invoking an operator.
As for real time results from when changing things from the properties panel, I don’t know if whether that can be done or not.
Can’t help but think this sounds like adding custom properties. These can be added from the object properties panel and you can edit the start and end numbers of the sliders too. Drivers using these properties give what appears to be a “real time” result. For instance the mouth rig posted by Cessan http://blenderartists.org/forum/showthread.php?t=201712&highlight=mouth+rig … if you set the animation going you can scrub the mouth open property that is on the jaw bone of the armature to make the mouth appear to talk.
I like to use a controller object that merely holds all the properties and use the convenient sliders that are all in one place. A few simple drivers lets you just keyframe in the properties… and saves writing any custom UI
Well what I have is a whole lot of shape keys on a mesh and I’m trying to create a nice UI for it as some of the keys should be modified in unison with others, and some of the keys correspond to different parameter ranges of a summary parameter like ‘head shape’.
Thanks batFINGER, I’ll have a look at using drivers and see if this scratches my itch
A quick note. There is a script here http://blenderartists.org/forum/showthread.php?t=203953&p=1751367&highlight=#post1751367 that goes thru the shape keys of object A and adds a driver to object B. I have one somewhere that does much the same except it adds the property to object C named after the shapekeys… etc. fecked if i can find it… It took me a while to find the add drivers code so i thought i’d post this.
I’ve implemented a hack, but its not pretty: just put the event code into the poll() method of the class.
This issue (how to get change events in a panel) seems to come up a few times in the forum but has never been resolved that I’ve found… here is an early reference to it: http://blenderartists.org/forum/showthread.php?t=196937&page=1. Is it a limitation of the current API?
If you use the object→action→settings paradigm, then your operator provides an “execute” method which gets called every time the user changes the settings put up by your “draw” method. You regenerate the output object anew each time, and Blender takes care of disposing of the old one. To the user, it looks like they’re adjusting the parameters of the object in real time, which is what you want.
I was hoping to see some kind of solution posted here, as my link was referenced above.
I am still looking for a way to “Extend” an object, not create an object.
Say I add a property to an Empty called “myProp”. This property is a float.
I still need a way to get an event when that float value is changed.
Remember, I don’t want my object properties to appear in the tool box window. I want them to appear in the object properties panel which is what they are extending. Currently, only an operator seems to be able to generate an event.
This is a step backwards from 2.49 where you could code events for any slider in your GUI. I would like to see the same thing in 2.5.
Wont any driver that references that property suffice especially now there is a way to add script functionality easily http://aligorith.blogspot.com/2011/01/rigging-faq-addedum-info-on-drivers.html . An onchange event could be set up quite simply by using a duplicate and passing the property values to a driver and firing your code if the values differ?
Ido - I had a look at the example you pointed to. For my application I really want then sliders as part of a panel in the the object context, rather that show up in the properties pane of the 3D view. Although Operator has an event mechanism Panel does not appear to have this.
One possibility is to use dynamic custom properties: http://wiki.blender.org/index.php/Doc:2.5/Manual/Extensions/Python/Properties#Dynamic_custom_properties and to trigger the change in the setter, but I can’t see how to do this without setting the property for the whole Object class. For my application I want around 50 sliders for a particular object - it seems silly to implement the properties for everything derived from Object, so I’d rather use ID-Properties. Besides, these then get saved with the blender file which is perfect for me.
The draw() method of the Panel class gets updated regularly so as a poor-mans event mechanism I store two custom properties - the actual value and an old value. I expose the actual value as a slider and check in draw() to see it it has changed from the old value and trigger the action if it has. This feels like very clumsy coding but hell, it works.
Here is an example:
import bpy
class OBJECT_PT_hello(bpy.types.Panel):
bl_label = "Test UI"
bl_space_type = "PROPERTIES"
bl_region_type = "WINDOW"
bl_context = "object"
@classmethod
def poll(self, context):
return "avatar" in context.active_object
def draw(self, context):
layout = self.layout
obj = context.active_object
try:
if obj['myprop~']!=obj['myprop']:
# <call routine here>
print("changed to:", obj['myprop'])
# reset old value
obj['myprop~'] = obj['myprop']
except KeyError as x:
print("Exception:",repr(x))
print("recreating Custom Properties")
obj['myprop']=0
obj['myprop~']=0
# creat UI
layout.prop(obj, "['myprop']", slider=True)