pyside:MEventMessageを使ったcallback


この記事は Maya Advent Calendar 2019 の14日目の記事になります。

大変恐縮ですが参加させていただきます。

maya上で状態が遷移した時に何らかの処理を実行したい場合
scriptJobが定番ですが、よりシンプルで軽いOpenMaya.MEventMessageを使用してみます。

今回はpysideGUI上での使用方法について簡単に書いてみました。
選択したノードのタイプを見てラベルの文字を変更してみましょう。

サンプルコード

meshをもつトランスフォームノードを選択した場合の処理と、異なるタイプが選択された場合の処理、
何も選択されていない場合の処理、それぞれ違うlabel textを表示させます。


import pymel.core as pm
import maya.api.OpenMaya as om

from PySide2 import QtGui, QtWidgets, QtCore
from maya.app.general.mayaMixin import MayaQWidgetBaseMixin

class TestGUI(MayaQWidgetBaseMixin, QtWidgets.QMainWindow):
    windowName = 'testGUI'

    def __init__(self, parent=None):
        super(TestGUI, self).__init__(parent)
        if pm.window(self.windowName, q=1, ex=1):
            pm.deleteUI(self.windowName)

        #window settings
        self.setObjectName(self.windowName)
        self.setAttribute(QtCore.Qt.WA_DeleteOnClose)
        self.setAttribute(QtCore.Qt.WA_AlwaysShowToolTips)
        self.setWindowTitle(self.windowName)
        self.setWindowFlags(QtCore.Qt.Window)

        self.initUI()
        self.setCentralWidget(self.mainWidget)
        self.connectCallback()

    def initUI(self):
        #UI初期設定
        self.mainWidget = QtWidgets.QWidget()
        main_vBoxLayout = QtWidgets.QVBoxLayout()
        self.mainWidget.setLayout(main_vBoxLayout)

        self.main_lbl = QtWidgets.QLabel('Select Mesh.')
        main_vBoxLayout.addWidget(self.main_lbl, alignment=QtCore.Qt.AlignCenter)     

    def closeEvent(self, event):
        #ウィンドウを閉じる際にcallbackを破棄
        om.MMessage.removeCallback(self.callback)

    def connectCallback(self):
        #callback作成
        self.callback = om.MEventMessage.addEventCallback('SelectionChanged', self.changeLabel)

    def changeLabel(self, *args, **kwargs):
        #選択したノードのタイプを判別してテキストを変更
        try:
            node = pm.selected()[0]
            if pm.nodeType(node.getShape()) == 'mesh':
                self.main_lbl.setText('Ready.')

            elif not pm.nodeType(node.getShape()) == 'mesh':
                self.main_lbl.setText('Must select mesh.')

            else:
                self.main_lbl.setText('Select Mesh.')

        except:
            node = None
            self.main_lbl.setText('Select Mesh.')

if __name__ == '__main__':
    gui = TestGUI()
    gui.show()

実行結果

テキストだけでなく様々なwidgetの状態切り替えもできますね。
短い内容でしたがご覧頂きありがとうございました。