忘却まとめ

Blenderの中級者・上級者向けの踏み込んだ情報や、アドオン・3DCGに関する情報を記事にします

アドオンのメニューを追加する・既存メニューを完全に置き換える・他アドオンのメニューも保持する【Blender/Python/アドオン】

Python

投稿日:

既存のメニューを消してアドオンAのメニューを追加しつつ、同様のメニュークラスにappendで寄生している別アドオンBを保持する方法を紹介する。

既存のメニューに追加する

def register():
	bpy.types.VIEWLAYER_PT_layer.append(viewlayer_list_menu)

def unregister():
	bpy.types.VIEWLAYER_PT_layer.remove(viewlayer_list_menu)

追加したい既存のメニュークラス名に、"append"により自分のメニューを追加することができる。
prependで前に追加・apendで後に追加。
この場合は、既存のメニューはそのまま。単純に機能追加するアドオンであればこれでよい。

既存のメニューを置き換える

既存のメニューレイアウトを改善するようなアドオンは、既存のメニューを完全に置き換えたくなる。

bpy.types.CLASS名.draw = 置き換えたいメニュー関数


上記の方法より、すべての既存メニューを自分のメニューに置き換えることができる。

既存のメニューを戻せるように保持しておく

アドオンを無効化時に元のメニューに戻すことができるように、bpy.types.CLASS名.drawを代入して保持しておくとよい。
登録解除時に、同じように~.drawに保持しておいたメニューを代入する。

def update_viewlayer_list(self, context):
	try:
		prefs = bpy.context.preferences.addons[__name__.partition('.')[0]].preferences
		if prefs.use_viewlayer_list:
			bpy.types.VIEWLAYER_PT_layer.draw = viewlayer_list_menu


		else:
			bpy.types.VIEWLAYER_PT_layer.draw = keep_VIEWLAYER_PT_layer

	except: pass

keep_VIEWLAYER_PT_layer = bpy.types.VIEWLAYER_PT_layer.draw

def register():
	update_viewlayer_list(None, bpy.context)

def unregister():
	try:
		bpy.types.VIEWLAYER_PT_layer.draw       = keep_VIEWLAYER_PT_layer
	except: pass

他アドオンのメニューをそのままにする

既存のメニューを完全に置き換える方法では、同じメニュークラスにappendなどで登録している他のアドオンBのメニューまで消えてしまう。
競合したアドオンが自分のアドオンであれば、隠しプロパティをアドオンBの方に追加することで解決できる。

アドオンBに隠しプロパティを追加

アドオンB側にプロパティを追加し、updateでメニュー追加を実行する隠し機能を作っておく。

# アドオンB

def update_vl_append_menu(self, context):
	bpy.types.VIEWLAYER_PT_layer.append(draw_buildenode_menu)


class BUILDENODE_AddonPreferences(AddonPreferences):
	bl_idname = __name__

	update_vl_append_menu : BoolProperty(update=update_vl_append_menu)

アドオンA側に、上記のプロパティを切り替える処理を追加する

メニューを空にする処理をした後に、上記で作ったプロパティを切り替えれば、そのメニューを保持することができる。

def update_viewlayer_list(self, context):
	try:
		prefs = bpy.context.preferences.addons[__name__.partition('.')[0]].preferences
		if prefs.use_viewlayer_list:
			bpy.types.VIEWLAYER_PT_layer.draw = viewlayer_list_menu
			if "build_export_node" in bpy.context.preferences.addons:
				bui_prefs = bpy.context.preferences.addons["build_export_node"].preferences
				bui_prefs.update_vl_append_menu = bool(not bui_prefs.update_vl_append_menu)


		else:
			bpy.types.VIEWLAYER_PT_layer.draw = keep_VIEWLAYER_PT_layer

	except: pass

その他

アドオンの登録順番は操作することができず、よって処理順番を操作することが難しい。
このような競合に対しては、再実行して上書きするような例外処理を作る他なさそう。

アドオンの制作依頼はこちら

-Python

Copyright© 忘却まとめ , 2021 All Rights Reserved Powered by STINGER.