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?


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
  • $\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 Nov 10 '14 at 16:04
  • $\begingroup$ Conversely is there a self.set method ? $\endgroup$ – Carel Jan 18 '16 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$ – pink vertex Jan 19 '16 at 14:54

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.

  • $\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 Nov 10 '14 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 Nov 10 '14 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 Nov 11 '14 at 20:40

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.