9
$\begingroup$

When using an Int- or FloatProperty, is there any way of changing their min and max values dynamically?

I'm currently loading images on the fly and would like to limit a frame property to run from 0 to len(loaded_images) every time I call the loading operator. However, the property seems to be read-only and re-assigning gives the following error:

bpy.context.scene.project_props.bl_rna.properties['myIntProp'] = bpy.props.IntProperty(...)
TypeError: bpy_prop_collection[key] = value: invalid, expected a StructRNA type or None, not a tuple

I understand the bpy.props constructor uses an intermediary tuple, but I'm not sure how to proceed. Is there any way around this?

$\endgroup$

2 Answers 2

10
$\begingroup$

You can not alter builtin properties deriving from bpy.types.Property. Just have a look at the api documentation. Every attribute is marked as readonly.

If you are using properties from bpy.props you can use your own setter and getter functions to check for min/max dynamically:

def get_frame(self):
    #default value=42
    return self.get('frame_custom', 42)  

def set_frame(self, value):
    #only accept values between min=0 and max=99
    if 0 <= value < 100: 
        self['frame_custom'] = value

bpy.types.Scene.frame_custom = bpy.props.IntProperty(name="Frame", get=get_frame, set=set_frame)

You could also wrap the scene attribute frame_current using:

def get_frame(self):
    return self.frame_current

def set_frame(self, value)
    if 0 <= value < 99:
        self.frame_current = value
$\endgroup$
3
  • $\begingroup$ Hmm, bummer, but looks like that's the way to go then. It just seems so "dirty" to have to keep track of the amount of custom images in an extra property. Thanks for your answer! $\endgroup$
    – Senshi
    Commented Nov 10, 2014 at 16:04
  • $\begingroup$ Conversely is there a self.set method ? $\endgroup$
    – Carel
    Commented Jan 18, 2016 at 14:19
  • $\begingroup$ In the first snippet the self.get method refers to bpy_struct.get. No, there is no self.set method. $\endgroup$ Commented Jan 19, 2016 at 14:54
6
$\begingroup$

You can't change anything in bl_rna, you can only set the min and max values in the constructor

... = bpy.props.*Property(min=..., max=...)

To change the boundaries after property registration, it would be required to re-register that property. It will remain its value, but it might leak memory or do weird stuff at some point, since it's not intended to be used like that.

Why do you want to change the possible value range at all? Just leave out the max parameter for almost infinite growth and use a low soft_max to make the widget behave nicer.

$\endgroup$
3
  • $\begingroup$ Thanks for the suggestion! I might try playing with re-registering just in case, but I definitely see what you're saying. The reason I want to change the max value is because at any time there are only a set number of images. If only 12 frames are loaded for this particular asset, it doesn't make sense to have the frame slider go up to 20, or 50 for example. Using just soft_max would be fine for me, but that too is read-only. $\endgroup$
    – Senshi
    Commented Nov 10, 2014 at 16:09
  • $\begingroup$ I agree such cases are not handled well in Blender, would make sense to allow callback functions for min/max attributes here, to give the slider a nice UX. $\endgroup$
    – CodeManX
    Commented Nov 10, 2014 at 19:43
  • $\begingroup$ That would definitely be a nice addition. I think a way to set the bounds directly could be a better solution in some cases though. Imagine having to iterate over all images/ objects in a collection every time to check for a property for example; that doesn't seem like something you'd nescesarily want executed every time? $\endgroup$
    – Senshi
    Commented Nov 11, 2014 at 20:40

You must log in to answer this question.

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