簡単に作れる MayaPyside-GUI

この記事は Maya-Python AdventCalendar2017 13日目の記事です。

qiita.com

pyside/pyside2 に対応した QtDesigner → Maya GUI の作成手順を紹介したいと思います。

QtDesignerで作成した.uiを.pyに変換してから使用する方法を紹介します。

こんなことありませんか?

  • Mayaでスクリプトを書くけどGUIが作れない...
  • MayaのGUIっていい感じにリサイズしてくれない...
  • めんどくさいからコマンドのままツール配布したけど誰も使ってくれない…

QtDesignerを使えば簡単に視覚的にGUIを作成出来ますよ!

では早速GUIを作っていきましょう。

0# 準備するもの

  • Autodesk Maya (2015 or 2016and2017 or 2018が望ましい)
  • お好みのエディタ (Maya の Script Editorでもいい) ちなみにおすすめは Atom です。

  • スクリプトテンプレート : こちらからダウンロードしたものをscriptsフォルダに配置してください。 scriptsフォルダにratetoolsをコピーして頂ければOKです。(PYTHONPATHが通ってれば何処でもOK)

今回使用するデータはこちらからダウンロードできます。 github.com

1# QtDesignerでGUIを作成する。

QtDesignerとはQtのWidgetアプリの画面を簡単に作成・編集することが出来るツールです。

f:id:ryunnnu:20171212130510p:plain

起動方法

mayaがインストールされていればインストールフォルダのbin\designer.exeから使用できます。

f:id:ryunnnu:20171212232655p:plain

C:\Program Files\Autodesk\Maya2016\bin\designer.exe

Mayaのバージョンによる designer.exe のバージョンの差は多分無いのでどれを使ってもOKです。

maya2017以降のバージョンのインストールフォルダに入っているdesigner.exeを使用する場合エラーが発生して使用できませんが、環境変数を追加することで使用することができます。(詳細は下記のリンクにて

knowledge.autodesk.com

使い方

GUIの構成は、ウィジェットボックスからウィジェットをドラッグ&ドロップして追加していきます。

今回は簡単にQListWiidgetとQPushButtonを使用したGUIを作成します。

↓こんな感じのGUIを作っていきますよ。

f:id:ryunnnu:20171212232334p:plain:w300

新しいフォーム > Main Window > 作成 で新規フォームを作成します。

左側のウィジェットボックスからList WidgetPush Buttonを配置します。(gif動画を参考に)

f:id:ryunnnu:20171212141147g:plain

  1. Push Button2つをHorizontal Layoutで横に並べます。
  2. 1.で作成したHorizontal LayoutList WidgetVartical Layoutで縦に並べます。
  3. 今回はメニューバーは使用しないので消します。
  4. ステータスバーも消します。
  5. 保存して完了です。 ratetools\pyside\template\template_GUI.uiという名前で保存してください。

ウィジェットの並びを整える最も簡単な方法として、組み込みのレイアウトマネージャーを使用します。

縦に並べたり、横に並べたり、グリッド状に並べたりしつつ、ウィンドウのリサイズ時に比率を保ってウィジェットの大きさを調整してくれます。

mayaコマンドで作成するGUIpysideで作成するGUIの一番分かりやすい差がこのレイアウトマネージメントです。※比率を個別に調節することもできます。

レイアウトマネージメントが活用できればmayaでGUIを作成しているときの煩わしさが一気に解消されるかと思います。

レイアウトクラス 説明
HorizontalLayout (QVBoxLayout) QBoxLayoutを継承し,上から下に縦に並べる。
VarticaLayout (QHBoxLayout) QBoxLayoutを継承し,左から右に横に並べる。
GridLayout (QGridLayout) 格子状に並べる。
FormLayout (QFormLayout) n行2列に並べる。ラベル付きで入力ウィジェットを並べることに特化。Qt 4.4で追加された並べ方。

QtDesigner内でもシグナル/スロットの設定ができますが、自分はGUIの作成のみで細かいコマンドの設定等は.pyに変換してから行います。

コマンドの設定は#4-GUIを拡張しようの項目でしていきたいと思います。

2# .uiをbatコマンドでpythonファイルに変換する。

batコマンドを利用して先ほど作成した.ui.pyに変換します。

pythonのパッケージにはpyside/pyside2は入っておらず、入れるのもめんどくさいのでmayapy.exeに元から入っているパッケージを利用して変換します。

ratetools/bat/ui2py_maya.bat.uiをドラッグ&ドロップすると.pyに変換できます。

ちなみに中身はこんな感じです。

pysideは2016以前のMaya pyside2は2017以降のmayapyで変換できます。(入ってないバージョンがある場合は環境によってパスを変更してご利用ください。

3# mayaでGUIを表示する。

.pyに変換した.uiをmayaで表示してみたいと思います。

ratetools\pyside\template\template_GUI.pyを使用してサクッとGUIを表示してみましょう。

下準備

先ほど変換した.pyは 34行目 と 36行目 の部分で読み込んでいます。

新しくツールを作った際はここを編集することで読み込むGUIを指定できます。

try :
    import template_GUI_pyside2 as qtGUI ;reload(qtGUI)
except:
    import template_GUI_pyside as qtGUI ;reload(qtGUI)

ウィンドウが既に表示されている場合、一旦閉じてから再度表示する処理を記述しています。

testToolWindowの部分をツールごとに変更してください。

最小化してあったら最大化する、閉じずに一番手前に表示する、ということもできるらしいです。(読み込みに時間がかかるツールはこういう手法をとりたいですね。)

def main():
    global testToolWindow

    try:testToolWindow.close()
    except:pass

    app = QApplication.instance()
    testToolWindow = GUI()
    testToolWindow.show()

    app.exec_()

Mayaで表示

mayaのScriptEditorで以下のコマンドを入力してください。

PYTHONPATHが通っていればQtDesignerで作成したGUIがそのまま表示されるかと思います。

from ratetools.pyside.template import template_GUI;reload(template_GUI)
template_GUI.main()

こんな感じ

f:id:ryunnnu:20171213004530p:plain

4# GUIを拡張しよう

QtDesignerで作成したGUIをMayaで表示できたでしょうか?

しかしこのままではボタンを押しても何も反応しないし、リストにも何も出てこないので、次はアクションの設定をしていきたいと思います。

ratetools\pyside\template\template_GUI.pyに処理を追記していきます。

1. PushButton(Addボタン)を押したときの処理

Addボタンを押したときに view上で選択しているオブジェクトをListWidgetに追加するコマンドを追記します。

GUIクラス内に関数を追加します。

class GUI(QMainWindow):
#省略
    def addList(self):#リストを空にしてアウトライナ上で選択しているアイテムをリストに追加する。
        getList=cmds.ls(sl=True)#選択しているオブジェクトを取得
        self.ui.listWidget.clear()#リストを空にして
        self.ui.listWidget.addItems(getList)#getListをリストに追加する

しかし関数を追加しただけではボタンを押しても反応しないので 関数とボタンを押されたというシグナルを接続します。 __init__関数にボタンが押された時の処理を追記します。

class GUI(QMainWindow):
#省略
    def __init__(self,parent=None):
    #省略
    self.ui.pushButton.clicked.connect(self.addList)

再度GUIを表示すると Addボタンを押したときに選択したオブジェクトがリストに登録されると思います。

f:id:ryunnnu:20171213024203p:plain

2. PushButton(Printボタン)を押したときの処理

続いてPrintボタンを押したときに選択されているリスト内のアイテムをプリントする処理を追記していきたいと思います。

先ほどと同じようにGUIクラス内に関数を追加します。

class GUI(QMainWindow):
#省略
    #省略
    def printList(self):#リスト内の選択しているアイテムをプリントする。
        getList=self.ui.listWidget.selectedItems()#リスト内の選択したアイテムを取得
        print [x.text() for x in getList]
        #オブジェクトとして取得されるので記述されている名前を取り出してプリントする。

アクションをシグナルにコネクトします。

class GUI(QMainWindow):
#省略
    def __init__(self,parent=None):
    #省略
    self.ui.pushButton.clicked.connect(self.addList)#Addボタンの処理
    self.ui.pushButton_2.clicked.connect(self.printList)#Printボタンの処理

見切れてるけど無事にプリントできました。

f:id:ryunnnu:20171213033602p:plain

少々物足りない内容だったかとは思いますが、こんな感じで作成したGUIに処理を加えていくと、Mayaコマンドとは一味違ったGUIを作成していくことができると思います。

ここでは記述しておりませんが、今回のサンプルデータにはリストをダブルクリックしたらオブジェクトを選択するアクションも追記しましたので是非試してみてください。

サンプルデータ ratetools/pyside/MaPyAdCa2017

ratetools/pyside/MaPyAdCa2017/MaPyAdCa2017_GUI.py

以下のコマンドでGUIを表示できます。

from ratetools.pyside.MaPyAdCa2017 import MaPyAdCa2017_GUI;reload(MaPyAdCa2017_GUI)
MaPyAdCa2017_GUI.main()

おわりに

急ぎ足になってしまいましたが、QtDesignerからPysideGUIを作成する手順を紹介しました。

まだpysideを触り始めて2,3ヵ月程度ですが、少しでもpysideの魅力を知っていただけたら幸いです。

今回紹介した以外にも様々な機能がありますので、pysideのリファレンスドキュメントを参考に自由に拡張みてはいかがでしょうか!!

Overview — PySide 1.1.0 documentation

今回使用したQListWidgetQPushButtonのリファレンスドキュメントはこちらになります。

https://deptinfo-ensip.univ-poitiers.fr/ENS/pyside-docs/PySide/QtGui/QListWidget.html

https://deptinfo-ensip.univ-poitiers.fr/ENS/pyside-docs/PySide/QtGui/QPushButton.html

pyside 情報ブログ

日々大変お世話になっているpysideの情報を発信してくださっているブログ様方を紹介します。

kiwamiden.com

https://unpyside.wixsite.com/unpyside unpyside

tm8r.hateblo.jp

flame-blaze.net

dftalk.jp

次回予告

明日 Maya Python Advent Calendar 2017 14日目は するとめがね:トモハラ さんです。

コナミコマンドダイアログの次は何が出てくるのでしょうか? 楽しみですね。

このGUIもpysideで作られているので興味のある方は是非見てくださいね! tm8r.hateblo.jp

ではでは