【MotionBuilder】Python SDK 入門 第7回 『UI・ツール開発 - SDK』
この記事は、Python SDK 入門 の第7回目の記事です。
今回から、MotionBuilder での UI・ツール開発がテーマです。SDKのみで完結する方法、Qt(PySide) を利用する方法、PySide の使用例の3つを、3回に分けて解説していきます。
UIの概説
MotionBuilderのUIがどんな構成で、各部がどんな名称をもつのか解説します。
MainWindow
パソコンで開く一つ一つのアプリケーションの”窓”としてのウィンドウと同じ。
MainWindow。赤枠で囲った部分
Window
MainWindowの次に大きい、別々の働きをもったUIの要素。
Window。カラーの枠で囲ったそれぞれの部分
一つ一つに固有の名前が付いており、Viewer Window, Navigator Window, Resources Window などがあります。これらの名前は各Window の中央上部に記載されていて、またウィンドウと同じようなアイコンが右上に表示されています。
経験上、この Window のタイトルを検索すると、調べたい機能がヒットしやすいです。
Windowの名称とホバー・削除ボタン
Layout
MainWindow において各Window を整列させたり、Window内でUIの要素を整列させたりするもの。
前者は ”Windowの配置” を定めるもので、画面左上メニュー「Layout」から選択できます。Layout が保存する Window の配置には専用の保存場所があり、以下の通りです。
-
MoionBuilder <version>/bin/config/Layouts/Base
デフォルトのレイアウト。
-
Document/MB/<version>/config/Layouts
ユーザーが作成したレイアウト。
Window内でUIの要素を整列させる働きとしての Layout は、前述のものと比べて視覚的にその存在を認識することはできません。
Region
各Windowにおいて、Layoutの中にUIの要素を埋め込むために確保される領域のようなもの。
これもまた視覚的にその存在を認識できるわけではありません。
Component
MotionBuilder のUIの最小の構成単位。
Component は Layout によって綺麗に整列されます。
1. Label, 2. Edit、3. Button
FBVisualComponentクラス
Visual Component base class.
All of the user interface elements available in the SDK derive from this class.
- FBVisualComponent Class Reference
MotionBuilder のUI要素作成を担う基底クラス。
ボタン(FBButton
)やラベル(FBlabel
)、ポップアップ(FBFilePopup
)なども全てこのクラスを継承しています。ただし、警告表示等でおなじみのメッセージボックス(FBMessageBox
)はこのクラスの派生クラスではありません。
FBToolクラス と Tool Manager
A tool in MotionBuilder is a new user interface layout adding to the current functionality of the software. Extensive user interface elements are available.
The
FBTool
class (found in the fbtool.h file) is manipulated as a layout, with all of the functionality that comes with a traditional layout. Regions can be added, moved, and controlled. MotionBuilder Help - Tools
ツール(Tool)は新たにUIを追加するもので、片仮名の”ツール”のイメージとは少々異なり、UIの要素の一つというイメージが近いです。FBTool
クラスも、FBVisualComponent
クラスを継承したFBLayout
クラスをさらに継承したクラスであるため、Layout と同等に扱われます。
Python で作成し、特定の操作で登録した Tool は Python Tool Manager にまとめられます。
Python Tool Manager Window
これはもちろんスクリプトでも確認できます。pyfbsdk_additions.FBGetTools()
は、Python Tool Manager に登録されている Tool の名前とそのインスタンスの辞書を返します。
import pprint
from pyfbsdk_additions import*
pprint.pprint(FBGetTools())
>>>
{'Batch Tool (scripted)': <BatchTool object at 0x000001AFC4E061B0>,
'Character Selection/Key Controls': <CharacterKeyer object at 0x000001AFC4E05BC0>,
'FBX Export': <pyfbsdk.FBTool object at 0x000001AFC4E098A0>,
'Keyboard Shortcuts Editor': <pyfbsdk.FBTool object at 0x000001AFC4EA7650>,
'SwitchingCameras': <pyfbsdk.FBTool object at 0x000001AFC4EED490>}
基本的なツールと関数等の解説
サンプルでよく見られる構成を用いたテンプレートで、UI・ツール作成に用いる基本的な関数等を解説します。
基本のテンプレート
# -*- coding: utf-8 -*-
# ラベル・リスト・ボタンから成る基本的なツール
from pyfbsdk import *
from pyfbsdk_additions import *
def PopulateLayout(tool: FBTool):
x = FBAddRegionParam(0,FBAttachType.kFBAttachLeft,"")
y = FBAddRegionParam(0,FBAttachType.kFBAttachTop,"")
w = FBAddRegionParam(0,FBAttachType.kFBAttachRight,"")
h = FBAddRegionParam(0,FBAttachType.kFBAttachBottom,"")
tool.AddRegion("RegionName","DisplayTitle", x, y, w, h)
vbox = FBVBoxLayout( FBAttachType.kFBAttachTop )
tool.SetControl("RegionName",vbox)
Label1 = FBLabel()
Label1.Caption = "Label1"
vbox.Add(Label1, 30)
List1 = FBList()
List1.style = FBListStyle.kFBDropDownList
for i in range(5):
List1.Items.append(str(i)) # list item must be string !!
vbox.Add(List1, 30, space = 10)
Button1 = FBButton()
Button1.Caption = "Button1"
vbox.Add(Button1, 30, space = 10)
def CreateTool():
t = FBCreateUniqueTool("BasicTool")
t.StartSizeX = 400
t.StartSizeY = 400
PopulateLayout(t)
ShowTool(t)
CreateTool()
pyfbsdk_additions
This module improves pyfbsdk UI building.
It provides Layout classes similar to classes found in Qt/GTK/Tcl/Tk that helps to manage region handling and UI control positioning. It also gives functions to create/destroy and manage Tools created in Python.
- pyfbsdk_additions Namespace Reference
pyfbsdk_additions
モジュールは、主にUIや Tool に関わる機能を提供するモジュールです。具体的には後述する FBCreateUniqueTool()
や FBVBoxLayout
などを定義しています。
FBCreateUniqueTool()
FBCreateUniqueTool(toolName: str) -> FBTool
この関数は "Tool の名前" を引数に取って Tool を作成し、Python Tool Manager に登録します。FBTool()
コンストラクタで作成した Tool は Tool Manager には登録されません。似た名前の関数で FBCreateTool()
がありますが、この関数は同名の Tool を作成した場合下図のように接尾辞がついて作成されます。
FBCreateTool()
で Tool を作成した場合
FBCreateUniqueTool()
の場合は、同名の Tool が既に作成されている場合はその Tool は削除され、新たに Tool が作成されます。
pyfbsdk_additions Namespace Reference
また、この関数は FBTool
型インスタンスを返します。FBLayout型は返しません。
FBLayout().AddRegion() / FBAddRegionParam()
FBLayout().AddRegion()
関数は、Layout に対して「位置・幅・高さ」を指定して UI構成要素の存在領域(Region)を確保する働きをします。この時「位置・幅・高さ」はただの数字で指定するのではなく特殊なパラメータを用いるのですが、そのパラメータを作成するのが FBAddRegionParam()
関数です。
FBAddRegionParam Class Reference
FBAttachType
は直接的には「UIのどこに沿わせるのか」を指定するのですが、これはUIを拡張・収縮させたときに構成要素がどう伴って動くか、を指定するのと同義です。
AddRegion()
関数についてドキュメントを調べるとその引数の多さに面食らいますが、下記のようにまとまりで考えると上記の FBAddRegionParam()
の引数と一致することが分かるでしょう。
FBLayout Class Reference
FBAddRegionParam()
関数を用いることで、AddRegion()
関数の記述が簡潔になります。
tool = FBTool()
# x,y,w,h はそれぞれFBAddRegionParam()で定義
tool.AddRegion("RegionName", "DisplayTitle", x, y, w, h)
次節で述べますが、AddRegion()
関数の第1引数「RegionName」は重要です。というのも、AddRegion()
関数でUI構成要素のための領域を確保した後は、その確保した領域にUI要素を据え置く操作が残っていて、その際にこの第1引数が必要だからです。
ちなみに、前節で FBCreateUniqueTool()
は FBLayout
型ではなく FBTool
型インスタンスを返すと書きましたが、FBTool
クラスはFBLayout
クラスを継承しているため、FBLayout.AddRegion()
が使用できます。
FBLayout().SetControl()
FBLayout().SetControl()
関数は、引数の Visual Component に対してその Layout内の Region の制御を与える、という働きをします。第1引数で Region名(前節で触れた、AddRegion()関数の第1引数)を、第2引数で FBVisualComponents
型インスタンスを指定します。
tool = FBTool()
label = FBLabel()
tool.SetControl("RegionName", label) # AddRegionで指定したRegion名を使う
こうして、予め確保した領域に対して各種UI構成要素を据え置くことができます。第6回の最後で MotionBuilderが落ちる原因を説明した際に触れたのは、これらの関数の引数が一致していないためにSetControl()
が Visual Component に対して存在しない Region の制御を許可しようとしたからです。
また、SetControl()
の第2引数には FBLayout
型インスタンスを指定することも可能です。
FBBoxLayout.Add()
上で紹介した FBAddRegion()
を用いることなく、簡単に Layout に対してボタンやラベルなどを配置できる関数です。ドキュメントでは一見引数が3つ、サンプルでは引数が2つのように見えますが、実際は通常の引数「size」とキーワード引数の「customparams」を引数に取ります。
FBVBoxLayoutの Add()
メンバ関数
FBVBoxLayout.Add()
では、space
, width
, height
の3つが指定できるようです。下記のように使います。
Button1 = FBButton()
vbox = FBVboxLayout()
vbox.Add(Button1, 30, space = 10, width = 100, height = 50)
キーワード引数の指定とその個数は任意です。
ShowTool()
この関数は OpenReality SDK Reference Guide にも Python Reference Guide にも登場しません。他の関数と同様に、help()
メソッドを用いて詳細を調べてみます。
この関数は FBTool
型インスタンスを引数に取り、その Tool を画面に表示するために専ら用いるようです。似た関数に ShowToolByName()
関数がありますが、これは Tool名 を指定して Tool を表示させることができます。もちろん、その名前をもつ Tool が事前に作成されていることが前提ですが。
ShowToolByName("Tool Name")
次回
今回は『UI・ツール開発』のテーマの初回として、SDKにおける基本的な概念と、基本の関数のみで完結するツールのテンプレートを示しました。次回は PySide とUI・ツール開発について詳しく解説していきます。
それでは、今回はここまで。最後までお読みくださりありがとうございました。
Discussion