Blenderのアドオン開発で複数ボタンを1つのOperatorクラスで作成する


経緯

PythonでBlenderのアドオンを開発するとき、パネルにパラメータが違うだけのボタンを複数置きたい場合

1つのOperatorクラス定義で、別々のパラメータのインスタンス(ボタン)を作るようにしたい
良い検索ワードが思いつかず調べるのに時間かかったので備忘録

確認したBlenderのバージョン

バージョン
3.1.2

方法

ボタンを表示するためのbpy.types.UILayout.operator()メソッドの戻り値で
bpy.types.OperatorProperties型のデータが返される
このデータ経由でOperatorクラス内に定義したプロパティの読み書きができる

bpy.types.UILayout.operator()を必要な回数呼び、それぞれの戻り値経由でプロパティを設定する

実装

以下の感じに実装

ボタン用のOperatorクラス定義
class MY_BRUSH_OT_Size(bpy.types.Operator):
    bl_idname = "my_brush_size.id"
    bl_label = "text"
    bl_options = {'REGISTER', 'UNDO'}

    #パラメータ用のプロパティ
    size: IntProperty(default=0, min=0, max=100, options={'HIDDEN'})

    def execute(self, context):
        # ウェイトペイントのブラシサイズを変更する
        bpy.context.scene.tool_settings.\
            unified_paint_settings.size = self.size
        return{'FINISHED'}
パネルでの描画
def draw(self, context):
    layout = self.layout
    row = layout.row(align=True)
    #btn: bpy.types.OperatorProperties
    btn = row.operator(MY_BRUSH_OT_Size.bl_idname, text="10")
    btn.size = 10 #プロパティ設定
    btn = row.operator(MY_BRUSH_OT_Size.bl_idname, text="20")
    btn.size = 20 #プロパティ設定
    btn = row.operator(MY_BRUSH_OT_Size.bl_idname, text="30")
    btn.size = 30 #プロパティ設定

結果

良い感じに動く

余談:ラジオボタン化

設定中のボタンの色を変えてラジオボタンのようにしたい場合は
bpy.types.UILayout.operator()depress引数でそれっぽくできる

  • 実装例
パネルでの描画(ラジオボタン化)
def draw(self, context):
    layout = self.layout
    row = layout.row(align=True)
    #現在のブラシサイズ取得
    cur_val = bpy.context.scene.tool_settings.unified_paint_settings.size

    #btn: bpy.types.OperatorProperties
    btn = row.operator(MY_BRUSH_OT_Size.bl_idname, text="10", depress=(cur_val == 10))
    btn.size = 10
    btn = row.operator(MY_BRUSH_OT_Size.bl_idname, text="20", depress=(cur_val == 20))
    btn.size = 20
    btn = row.operator(MY_BRUSH_OT_Size.bl_idname, text="30", depress=(cur_val == 30))
    btn.size = 30
  • 結果
    現在選択されているボタンが分かりやすくなる

参考

https://memoteu.hatenablog.com/entry/2019/06/17/132448