【Maya Python】QtDesignerで作成した.uiをMayaで表示する


はじめに

【Maya Python】スクリプトの中身を噛み砕く123で書いたスクリプトの書き方では小さいスクリプトでは問題ありませんが、複雑なUIを作ろうとすると大変な労力がかかります。
そこでQtDesignerを使用しUIを組み立ててみようと思います。
CGアーティストとしてはスクリプトで悩むよりこういったわかりやすいツールがあるといいですね。
今回はとりあえず触ってみて感じを掴むためにMayaでUIを表示して簡単な動作をさせるところまで作ってみたいと思います。
PySideとPySide2、PyQt5などやり方が散見されているので自分の備忘録も兼ねて書きます。
動作環境はMaya2019,2020です。

UIファイルを用意する

とりあえずこんな感じにUIを作ってみました。

作り方についてはこちらのサイトを参考。

PyQt5とpython3によるGUIプログラミング:実践編[0]
第5章 Qt Designerを使ってみよう
QtDesignerでUIを作る

少し詰まったところをメモ

レイアウトの設定をしっかりやる
そのまま配置しただけだと、ウィンドウサイズを変更してもUIが追従してくれなかったり、ウィンドウ立ち上げ時にウィンドウが小さすぎるなど起こってしまう。

図のようにcentralwidgetがbrakeLayoutになっていると全部表示してくれない。

レイアウトを設定し、ウインドウサイズを調整後、Size Constraintsで最小サイズを設定する。するとちゃんと収まった状態のウィンドウを作ることができる。ウィンドウサイズを変更してもUIが追従してくれる。

レイアウト設定後の初期起動時図

ウィンドウを表示するプログラムを用意する

ひとまずコード全文

# -*- coding: utf-8 -*-
from PySide2 import QtWidgets
from PySide2.QtUiTools import QUiLoader
from maya.app.general.mayaMixin import MayaQWidgetBaseMixin

# パスを直接指定
UIFILEPATH = 'C:/Users/YN/Desktop/testUI.ui'

## MainWindowを作るクラス
class MainWindow(MayaQWidgetBaseMixin, QtWidgets.QMainWindow):
    def __init__(self, parent=None):
        super(MainWindow, self).__init__(parent)
        # UIのパスを指定
        self.UI = QUiLoader().load(UIFILEPATH)
        # ウィンドウタイトルをUIから取得
        self.setWindowTitle(self.UI.windowTitle())
        # ウィジェットをセンターに配置
        self.setCentralWidget(self.UI)

        # ボタンを接続
        self.UI.refreshPushButton.clicked.connect(self.refreshPushButton)

    def refreshPushButton(self):
        print ('refresh')

## MainWindowの起動
def main():
    window = MainWindow()
    window.show()

if __name__ == '__main__':
    main()

スクリプトエディターにコピペして、
UIFILEPATHを先ほど作成したuiのパスに設定します。
そして実行すればひとまず作成したUIをMayaで確認できます。

プログラム詳細

UIをロード

from PySide2.QtUiTools import QUiLoader
UIをロードするにはQtUiToolsからQUiLoaderをインポートします。

self.UI = QUiLoader().load(UIFILEPATH)
UIFILEPATHを読み込み、self.UIとしてインスタンスします。

UIから値を取得

self.setWindowTitle(self.UI.windowTitle())
ウィンドウタイトルを指定しないと適当な名前でウィンドウが作成されるためウィンドウタイトルを作成したUIファイルから取得します。もちろんここにstringで入力することも可能です。
self.UI.windowTitle()
UIの中のプロパティ名を指定すればそこに設定されている値を取得できます。

このように設定しておけばプログラムで書き換えずともUIファイルを変更すればいいので便利です。

UIを配置

self.setCentralWidget(self.UI)
UIを配置します。

ボタンの動作を作成

self.UI.refreshPushButton.clicked.connect(self.refreshPushButton)
objectNameがrefreshPushButtonのボタンに、クリックしたときの機能を接続します。

このようにQtDesignerでオブジェクト名を指定しておきます。

    def refreshPushButton(self):
        print ('refresh')

ボタンを押したときに、refreshとプリントするような機能をつけました。
実際は、ここにこのボタンに設定したい機能を書き込んで行きます。

おわりに

私も、はじめはどこから手を付ければいいか暗中模索状態だったので、なにかの役に立てればと思います。
MayaでとりあえずサクッとUI表示してあー、こうなってるのねというのがわかってくればどんどんUIを複雑にしていけるんじゃないでしょうか。

MayaのPySide2は途中でPySideからアップデートがあり、記述の仕方が変わったため混乱しました。また似たようなPyQt5など検索にヒットしてしまうため更にややこしいですね。。

参考

大変参考になりました。ありがとうございます。

PyQt5とpython3によるGUIプログラミング:実践編[0]
第5章 Qt Designerを使ってみよう
QtDesignerでUIを作る