夜風のMixedReality

xRと出会って変わった人生と出会った技術を書き残すためのGeekなHoloRangerの居場所

BlenderPythonで状態に応じて表示されるボタンを変える実装を行う

本日はBlender枠です。

今回はBlenderでボタンを押したらそれをトリガーにUIを更新する実装を行います。

Blenderでボタンを押すとボタンが消える実装

Blenderに限らずUIを実装する上で、最初の一回やある条件下にあるときのみ選択可能にするというユースケースは非常にあります。

例えば、ボタンを一度のみクリックできる実装は次のようになります。

import bpy

# カスタムパネルの定義
class CustomPanel(bpy.types.Panel):
    bl_label = "カスタムパネル"
    bl_idname = "PT_CustomPanel"
    bl_space_type = 'VIEW_3D' 
    bl_region_type = 'UI'
    bl_category = 'Tool' #Toolタブに表示

    def draw(self, context):
        layout = self.layout

        if not context.scene.button_clicked:
            # パネル内にボタンを配置
            layout.operator("my_operator.my_button", text="ボタンをクリック")

# カスタムオペレータの定義
class MyOperator(bpy.types.Operator):
    bl_idname = "my_operator.my_button"
    bl_label = "ボタンをクリック"

    def execute(self, context):
        # ボタンがクリックされた時に実行されるコードをここに書く
        self.report({'INFO'}, "ボタンがクリックされました")
        
        # ボタンを非表示にする
        context.scene.button_clicked = True
        
        return {'FINISHED'}

# プラグインを登録するための関数
def register():
    bpy.utils.register_class(CustomPanel)
    bpy.utils.register_class(MyOperator)
    bpy.types.Scene.button_clicked = bpy.props.BoolProperty(default=False)

# プラグインをアンリリースするための関数
def unregister():
    bpy.utils.unregister_class(CustomPanel)
    bpy.utils.unregister_class(MyOperator)
    del bpy.types.Scene.button_clicked

if __name__ == "__main__":
    register()

上記コードではscene.button_clickedという変数を用意し、bpy.types.Scene.button_clicked = bpy.props.BoolProperty(default=False)でBool型として初期値Falseで実装しています。

ボタンを押すイベントが以下になります。

class MyOperator(bpy.types.Operator):
    bl_idname = "my_operator.my_button"
    bl_label = "ボタンをクリック"

    def execute(self, context):

        self.report({'INFO'}, "ボタンがクリックされました")
        
        # ボタンを非表示にする
        context.scene.button_clicked = True
        
        return {'FINISHED'}

この際にcontext.scene.button_clickedをTrueに変えます。

Trueの場合でボタンの表示が走らず実行がされなくなります。

    def draw(self, context):
        layout = self.layout

        if not context.scene.button_clicked:#falseの場合のみ実行
            # パネル内にボタンを配置
            layout.operator("my_operator.my_button", text="ボタンをクリック")

以上が状態に応じてボタンを消す処理になります。

〇ボタンを切り替える。

上記ではボタンが押されたらボタンの表示を消すということを行いましたが、応用すればボタンを押すことで違うボタンに切りかえられます。

用途としてはスタートに対してストップなど対になっている動作などに使用できます。

import bpy

# カスタムパネルの定義
class CustomPanel(bpy.types.Panel):
    bl_label = "カスタムパネル"
    bl_idname = "PT_CustomPanel"
    bl_space_type = 'VIEW_3D' 
    bl_region_type = 'UI'
    bl_category = 'Tool' # Toolタブに表示

    def draw(self, context):
        layout = self.layout

        if not context.scene.button_clicked:
            # パネル内にボタンを配置
            layout.operator("my_operator.my_button", text="ボタンをクリック")
        else:
            layout.operator("my_operator2.my_button2", text="Close")

# カスタムオペレータの定義
class MyOperator(bpy.types.Operator):
    bl_idname = "my_operator.my_button"
    bl_label = "ボタンをクリック"

    def execute(self, context):
        # ボタンがクリックされた時に実行されるコードをここに書く
        self.report({'INFO'}, "ボタンがクリックされました")
        
        # ボタンを非表示にする
        context.scene.button_clicked = True

        # パネルを再描画
        bpy.context.area.tag_redraw()

        return {'FINISHED'}
    
class MyOperator2(bpy.types.Operator):
    bl_idname = "my_operator2.my_button2"
    bl_label = "Close"
    
    def execute(self, context):
        # ボタンを非表示にする
        context.scene.button_clicked = False

        # パネルを再描画
        bpy.context.area.tag_redraw()

        return {'FINISHED'}

# プラグインを登録するための関数
def register():
    bpy.utils.register_class(CustomPanel)
    bpy.utils.register_class(MyOperator)
    bpy.utils.register_class(MyOperator2)
    bpy.types.Scene.button_clicked = bpy.props.BoolProperty(default=False)

# プラグインをアンリリースするための関数
def unregister():
    bpy.utils.unregister_class(CustomPanel)
    bpy.utils.unregister_class(MyOperator)
    bpy.utils.unregister_class(MyOperator2)
    del bpy.types.Scene.button_clicked

if __name__ == "__main__":
    register()

これによってボタンを一度押すことで表示が切り替わり違う機能を持ったボタンとして使用できます。

本日は以上です。