【Blender Python】blender的属性的操作
扩展 Material/Object 的属性(属性组)
import bpy
class MaterialSettings(bpy.types.PropertyGroup):
my_int: bpy.props.IntProperty()
my_float: bpy.props.FloatProperty()
my_string: bpy.props.StringProperty()
bpy.utils.register_class(MaterialSettings)
bpy.types.Material.my_settings = bpy.props.PointerProperty(type=MaterialSettings)
# test the new settings work
material = bpy.data.materials[0]
material.my_settings.my_int = 5
material.my_settings.my_float = 3.0
material.my_settings.my_string = "Foo"
import bpy
class ObjectSettings(bpy.types.PropertyGroup):
my_int: bpy.props.IntProperty()
my_float: bpy.props.FloatProperty()
my_string: bpy.props.StringProperty()
bpy.utils.register_class(ObjectSettings)
bpy.types.Object.my_settings = bpy.props.PointerProperty(type=ObjectSettings)
集合属性的简单使用
import bpy
# Assign a collection.
class SceneSettingItem(bpy.types.PropertyGroup):
name: bpy.props.StringProperty(name="Test Property", default="Unknown")
value: bpy.props.IntProperty(name="Test Property", default=22)
bpy.utils.register_class(SceneSettingItem)
bpy.types.Scene.my_settings = bpy.props.CollectionProperty(type=SceneSettingItem)
# Assume an armature object selected.
print("Adding 2 values!")
my_item = bpy.context.scene.my_settings.add()
my_item.name = "Spam"
my_item.value = 1000
my_item = bpy.context.scene.my_settings.add()
my_item.name = "Eggs"
my_item.value = 30
for my_item in bpy.context.scene.my_settings:
print(my_item.name, my_item.value)
- 更新一个集合属性的update
import bpy
def update_func(self, context):
print("my test function", self)
bpy.types.Scene.testprop = bpy.props.FloatProperty(update=update_func)
bpy.context.scene.testprop = 11.0
属性的Get/Set操作
import bpy
# Simple property reading/writing from ID properties.
# This is what the RNA would do internally.
def get_float(self):
return self["testprop"]
def set_float(self, value):
self["testprop"] = value
bpy.types.Scene.test_float = bpy.props.FloatProperty(get=get_float, set=set_float)
# Read-only string property, returns the current date
def get_date(self):
import datetime
return str(datetime.datetime.now())
bpy.types.Scene.test_date = bpy.props.StringProperty(get=get_date)
# Boolean array. Set function stores a single boolean value, returned as the second component.
# Array getters must return a list or tuple
# Array size must match the property vector size exactly
def get_array(self):
return (True, self["somebool"])
def set_array(self, values):
self["somebool"] = values[0] and values[1]
bpy.types.Scene.test_array = bpy.props.BoolVectorProperty(size=2, get=get_array, set=set_array)
# Enum property.
# Note: the getter/setter callback must use integer identifiers!
test_items = [
("RED", "Red", "", 1),
("GREEN", "Green", "", 2),
("BLUE", "Blue", "", 3),
("YELLOW", "Yellow", "", 4),
]
def get_enum(self):
import random
return random.randint(1, 4)
def set_enum(self, value):
print("setting value", value)
bpy.types.Scene.test_enum = bpy.props.EnumProperty(items=test_items, get=get_enum, set=set_enum)
# Testing the properties:
scene = bpy.context.scene
scene.test_float = 12.34
print('test_float:', scene.test_float)
scene.test_array = (True, False)
print('test_array:', tuple(scene.test_array))
# scene.test_date = "blah" # this would fail, property is read-only
print('test_date:', scene.test_date)
scene.test_enum = 'BLUE'
print('test_enum:', scene.test_enum)
属性内部的结合Menu 操作
```python
import bpy
class BasicMenu(bpy.types.Menu):
bl_idname = "OBJECT_MT_select_test"
bl_label = "Select"
myint1 = bpy.props.IntProperty(name = "myin1", max = 100, min = 0, subtype = 'PERCENTAGE')
myint2 = bpy.props.IntProperty(name = "myin2", max = 100, min = 0, subtype = 'FACTOR')
bpy.types.Scene.myint1 = myint1
bpy.types.Scene.myint2 = myint2
def draw(self, context):
layout = self.layout
layout.prop(bpy.context.scene, 'myint1')
layout.prop(bpy.context.scene, 'myint2')
op1 = layout.operator("object.select_all", text="Select/Deselect All")
op1.action = 'TOGGLE'
layout.operator("object.select_all", text="Inverse").action = 'INVERT'
layout.operator("object.select_random", text="Random")
bpy.utils.register_class(BasicMenu)
# test call to display immediately.
#bpy.ops.wm.call_menu(name="OBJECT_MT_select_test")
bpy.ops.wm.call_menu(name=BasicMenu.bl_idname)
属性在 UI 里的灵活使用
from decimal import MIN_ETINY
import bpy
from numpy import size
from .ops import Test_Ops, Test_Ops2
class OP(bpy.types.Operator):
bl_idname = "test.enum_ops"
bl_label = "Enum Op"
# (identifier, name, description, icon, number)
# (identifier, name, description, number)
myitems = [("HIGH", "This is high","test1", 1),
("MED", "This is medium","test2", 2),
("LOW", "This is low","test3", 3)]
myenum: bpy.props.EnumProperty(items=myitems)
def execute(self, context):
return {"FINISHED"}
bpy.utils.register_class(OP)
class Test_Panel(bpy.types.Panel):
# 标签
bl_label = 'a-test'
bl_idname = 'A_TEST_PL'
# 面板所属区域
bl_space_type = "VIEW_3D"
# 显示面板的地方
bl_region_type = "UI"
# 显示面板的地方的归类
bl_category = "A-TEST"
myint1 = bpy.props.IntProperty(name="myint1", max=100, min=0, default=50, subtype='PERCENTAGE')
bpy.types.Scene.myint1 = myint1
myint2 = bpy.props.IntProperty(name='myint2', max=100, min=0, default=50, subtype='FACTOR')
bpy.types.Scene.myint2 = myint2
mystr1 = bpy.props.StringProperty(name="mystr1", default="C:/Users/LMX" ,subtype='DIR_PATH')
bpy.types.Scene.mystr1 = mystr1
mystr2 = bpy.props.StringProperty(name="mystr2", default="C:/Users/LMX/test.txt" ,subtype='FILE_PATH')
bpy.types.Scene.mystr2 = mystr2
mybool1 = bpy.props.BoolProperty(name="mybool1", default=True, subtype='TIME')
bpy.types.Scene.mybool1 = mybool1
mybool2 = bpy.props.BoolProperty(name="mybool2", default=True, subtype='TIME')
bpy.types.Scene.mybool2 = mybool2
# (identifier, name, description, icon, number)
# (identifier, name, description, number)
myitems = [("HIGH", "This is high","test1", 1),
("MED", "This is medium","test2", 2),
("LOW", "This is low","test3", 3)]
myenum1 = bpy.props.EnumProperty(items=myitems, name="myenum1")
bpy.types.Scene.myenum1 = myenum1
myenum2 = bpy.props.EnumProperty(items=myitems, name="myenum2")
bpy.types.Scene.myenum2 = myenum2
vfloat1 = bpy.props.FloatVectorProperty(size=6)
bpy.types.Scene.vf1 = vfloat1
vfloat2 = bpy.props.FloatVectorProperty(size=3, subtype='COLOR')
bpy.types.Scene.vf2 = vfloat2
def draw(self, context):
layout = self.layout
col = layout.column()
col.operator_enum(OP.bl_idname, property='myenum')
col.operator(Test_Ops.bl_idname)
col.operator(Test_Ops2.bl_idname)
col.prop(bpy.context.scene, 'mystr1')
col.prop(bpy.context.scene, 'mystr2')
col.prop(bpy.context.scene, 'myint1')
col.prop(bpy.context.scene, 'myint2')
col.prop(bpy.context.scene, 'mybool1')
col.prop(bpy.context.scene, 'mybool2', toggle=True)
col.prop(bpy.context.scene, 'myenum1')
colrow = col.row()
colrow.prop(bpy.context.scene, 'myenum2', expand=True)
col.prop(bpy.context.scene, 'vf1')
col.prop(bpy.context.scene, 'vf2')
效果: