2016年12月12日月曜日

Maya PySide.QWidgetへ標準UIを追加する

PySideでのUI作成はわかりやすくていいんですが、スライダと一体になったMayaのUIなども捨てがたく両方とも使いたい場合。


例としてアウトライナでの表示色を設定するダイアログです。下段のボタン3つはQPushButtonです。上段はColorSliderGrpでMayaの標準のUIです。PySideとMaya標準UIが混在しています。ベースはQWidgetを使って作成&レイアウトされたウィンドウになります。

厳密には両方同じQtなので「混在」ではありませんが、それはさておき、、、

混在させると一口に言っても、
  1. PySideでレイアウトされたGUIへMaya標準UIをアタッチする
  2. Maya標準UI レイアウトへPySide.QtGuiのウィジットをアタッチする
の2通りがあると考えられますが、今回は1の方法です。

PySideでレイアウトされたUI(QLayoutを使用したレイアウト)へMayaの標準のUIを表示するには、setParentする先のレイアウト名の文字列が必要になります。

このとき、setParentできるように、setObjectName()を使用してQLayoutへ名前をつけますが、すでに同じ名前のものがある場合などはそちらにアタッチされるかもしれませんので、必ずユニークな名前をつけておきます。ユニーク名前のためにuuidモジュールを使用します。

import uuid
print str(uuid.uuid4())

とすると、ランダムなUUID文字列が取り出せます。まぁまぁランダムなものなのだそうで、適当なレイアウト名にこれを追加してユニークなオブジェクト名とします。

あとはsetParent(オブジェクト名)とすれば以降に作成するMayaのUIコントロールが指定したレイアウトへアタッチされていきます。

以下がスクリプトのサンプルです。メインになる実装は省いています。全ての実装を含み機能するモノは投稿の最後にあります。

# coding: utf-8

'''Set outliner color to selected objects

Example: Regist to shelf following 2 line as Python

import HtSetOutlinerColor
HtSetOutlinerColor.main()

Auther: Hiroshi Takashima, Canplaize Inc.
License: CC BY-SA 4.0
'''

import pymel.core as pm
import uuid
from maya.cmds import colorManagementConvert #2016.5 pymelにないので拝借
from pymel.core.language import Mel as mel
try:
 from PySide2.QtWidgets import *
 from PySide2.QtCore import *
 from PySide2.QtGui import *
except ImportError:
 from PySide.QtCore import *
 from PySide.QtGui import *
import maya.OpenMayaUI as omui
from maya.app.general.mayaMixin import MayaQWidgetBaseMixin

class HtSetOutlinerColorDialog(MayaQWidgetBaseMixin,QWidget):
 def __init__(self, *args, **kwargs):
  super(HtSetOutlinerColorDialog, self).__init__(*args, **kwargs)
  self.closeOtherInstance()
  self.setAttribute(Qt.WA_DeleteOnClose, True)
  self.initUI()

 def initUI(self):
  self.setWindowTitle("Set Outliner color")
  
  #Main Layout
  self.layout_main = QVBoxLayout()
  #ユニークなオブジェクト名をつける
  self.layout_main.setObjectName("HtSetOutlinerColorDialog_mainLayout_" + str(uuid.uuid4()))
  self.setLayout(self.layout_main)
  
  #add Maya UI to QHBoxLayout
  pm.setParent(self.layout_main.objectName()) #名付けたオブジェクト名を使用してsetParent()
  self.pmColorSliderGrp = pm.uitypes.ColorSliderGrp()

  layout_ApplyCloseButton = QHBoxLayout()
  self.Button_disableColor = QPushButton("Don't Use")
  self.Button_apply = QPushButton("Apply")
  self.Button_close = QPushButton("Close")
  layout_ApplyCloseButton.addWidget(self.Button_disableColor)
  layout_ApplyCloseButton.addStretch()
  layout_ApplyCloseButton.addWidget(self.Button_close)
  layout_ApplyCloseButton.addWidget(self.Button_apply)
  self.layout_main.addLayout(layout_ApplyCloseButton)
  
  self.Button_disableColor.clicked.connect(self.clickDisableColor)
  self.Button_close.clicked.connect(self.clickClose)
  self.Button_apply.clicked.connect(self.clickApply)

 def clickDisableColor(self):
  pass

 def clickClose(self):
  self.close()

 def clickApply(self):
  pass

 def closeOtherInstance(self):
  [widget.close() for widget in self.parent().findChildren(self.__class__) if widget is not self]

def main():
 dlg = HtSetOutlinerColorDialog()
 dlg.show()
 return dlg

if __name__ == '__main__':
 main()

ダウンロード:HtSetOutlinerColor
WindowsのMaya2016 Ext2と2017で動作確認済みです。

スクリプトフォルダへ「__init__.py」を含むHtSetOutlinerColorフォルダをコピーし、
import HtSetOutlinerColor
HtSetOutlinerColor.main()
をShelfへ登録し実行です。

0 件のコメント:

コメントを投稿