プロパティの更新を1つの機能に一元化しますか?[複製]

Dec 14 2020

その更新機能から小道具のいくつかのより多くの情報を得る方法はありますか?

以下の例では、残念ながら、selfはprop自体ではなくbpy.types.Sceneを指し示します。そのため、一見すると、更新機能から小道具の情報を取得できないように見えます。また、すべての小道具で機能する単一の集中更新機能ではなく、小道具ごとに1つの更新機能が必要になります。

setからより多くの情報を取得できますが、もちろん、prop値を変更するとフィードバックループが作成されることに注意してください。)

私が間違っていることを証明してください

def update(self,context):
    print("what is this prop value?")
    print("what is this prop api?")
    print("what is this prop name?")
    return None 

bpy.types.Scene._prop          : bpy.props.FloatProperty(default=1.0 , name="Prop", update=update)
bpy.types.Scene._prop_this     : bpy.props.FloatProperty(default=1.1 , name="Prop This", update=update)
bpy.types.Scene._prop_that     : bpy.props.FloatProperty(default=1.2 , name="Prop That", update=update)
bpy.types.Scene._prop_another  : bpy.props.FloatProperty(default=1.3 , name="Prop Another", update=update)

回答

5 batFINGER Dec 14 2020 at 20:22

ジェネリック関数を作成して、更新メソッドを作成します。

@pinkvertexがそれを見つけることができなかったというこれに非常に類似した別の答えがあります。

更新メソッドとして1つの関数を使用する代わりに、プロパティを渡すメソッドファクトリを作成します。

サンプルコード、およびサンプル実行(かなり自明)、

import bpy
from bpy.props import FloatProperty
from bpy.types import Scene


def update(prop):
    def update(self, context):
        print(f"Update {prop} of {self}")
        return None
    return update


for prop in ("prop_this", "prop_that", "prop_another"):
    setattr(
        Scene, 
        prop,
        FloatProperty(
            default=1.0,
            name="Prop", 
            update=update(prop)
            )
        )

サンプル実行。

>>> C.scene.prop_this
1.0

>>> C.scene.prop_this = 4
Update prop_this of <bpy_struct, Scene("Scene") at 0x7fc97bff8008>

>>> 

質問コードに関して2つのことがあります。

  • プロパティは、注釈としてではなく、タイプに割り当てられます。クラス定義でアノテーションを使用します。

    アンダースコアで始まるプライベート変数は作成できません。

     >>> bpy.types.Scene._prop = bpy.props.FloatProperty()
     Traceback (most recent call last):
     File "<blender_console>", line 1, in <module>
     ValueError: bpy_struct "Scene" registration error: _prop could not register because the property starts with an '_'