26
25

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

Maya-PythonAdvent Calendar 2016

Day 14

【補完】[PySide] QtDesignerで遊ぼう

Last updated at Posted at 2016-12-14

PySideの勉強(に伴うQtDesignerの勉強)でお世話になっているこちらの記事

[PySide] QtDesignerで遊ぼう @ mtazmi-Lab
http://mtazmi-lab.blogspot.jp/2013/01/QtDesiner.html

につきまして、
ここで作られているUIを受けて、情報を取得したりなんか発行したりするスクリプトを書いてみたいと思います。

mtazmiさんありがとうございます、お世話になっておりますm(_ _ )m

承前

どういうことかと申しますと、
こちらの記事は QtDesignerでのUIづくり についてのステキ記事で、
その前後記事でもPySideならびにQtDesignerを使った事例を解説しておられます。

ただ、当該記事に登場するUIそのものについては動作部分が用意されておりませんでしたので、
MAXリスペクトしつつその点を補完した小ネタを書かせていただきたい、
と思った次第です。

補足

前後の記事はこちらです。ぜひあわせてどうぞ

[PySide] PySideで遊んでみるよ
http://mtazmi-lab.blogspot.jp/2012/12/pythonPySide01.html

[PySide] UIからいろいろな値を取ろう
http://mtazmi-lab.blogspot.jp/2013/01/pysidegetvalue.html

前者は今回の路線に比較的近く、
後者はQtDesignerを用いないPySideによるスクラッチです

UIの準備

元記事に添ってUIを作成しましょう。
ちなみにQtDesignerはMayaインストールフォルダのbin以下にいる
designer.exe がそれです。

C:\Program Files\Autodesk\Maya{ver}\bin\designer.exe

しんちょく1
01.png

しんちょく2
02.png

できました
.uiファイルをよきところに保存します。
ファイル名はここではmayapyAdCl.uiとしています。

動作部

動作部を作っていきます。

まずもと記事のスクリプトがこちら

# -*- coding: utf-8 -*-
 
import os
import sys
 
from PySide import QtCore, QtGui
from PySide.QtUiTools import QUiLoader
 
CURRENT_PATH = os.path.dirname(__file__)
 
#----------------------------------------------------------------------------
## GUIを作るクラス
class GUI(QtGui.QMainWindow):
 
    def __init__(self, parent=None):
        super(GUI, self).__init__(parent)
        loader = QUiLoader()
        uiFilePath = os.path.join(CURRENT_PATH, 'mayapyAdCl.ui')
        self.UI = loader.load(uiFilePath)
        self.setCentralWidget(self.UI)
 
#------------------------------------------------------------------------------ 
## GUIの起動
def main():
    app = QtGui.QApplication(sys.argv)
    app.setStyle('plastique')    # ← ここでスタイルを指定
    ui = GUI()
    ui.show()
    sys.exit(app.exec_())
 
 
if __name__ == '__main__':
    main()
 
#-----------------------------------------------------------------------------
# EOF
#-----------------------------------------------------------------------------

これを先程の .ui と同じとこに保存します。
名前は mayapyAdCl.py としておきます。

動作部を追加

元記事のひとつまえの記事を参考に、
あとPySideのドキュメントも眺めながら、下記のようにしてみます。

# -*- coding: utf-8 -*-

from PySide import QtCore, QtGui
from PySide.QtUiTools import QUiLoader

import maya.cmds as cmds
from maya.app.general.mayaMixin import MayaQWidgetBaseMixin

CURRENT_PATH = os.path.dirname(__file__)

#----------------------------------------------------------------------------
## GUIを作るクラス
class GUI(MayaQWidgetBaseMixin, QtGui.QMainWindow):
 
    def __init__(self, parent=None):
        super(GUI, self).__init__(parent)
         
        # uiファイルのロード
        loader = QUiLoader()
        uiFilePath = os.path.join(CURRENT_PATH, 'mayapyAdCl.ui')
        self.UI = loader.load(uiFilePath)
        self.setCentralWidget(self.UI)
         
        # ウインドウのタイトルを指定
        self.setWindowTitle(u'UIのサンプルだよ')
        # ウインドウのサイズを指定
        self.resize(256, 128)
         
        # UI要素にシグナルを追加
        self.setSignals()
 
    #----------------------------------------
    ## シグナルの登録
    # @param None
    # @return None
    def setSignals(self):
        # applyボタンを押したときの動作
        self.UI.apply_btn.clicked.connect(self.doIt)
        # apply and closeボタンを押したときの(ry
        self.UI.applyClose_btn.clicked.connect(self.doIt_close)
        # closeボタン(ry
        self.UI.close_btn.clicked.connect(self.close)

    ## チェックが入ってたらロックする
    def doIt(self):
        chbxState = {
                     'tx':self.UI.tx_chbx.isChecked(),
                     'ty':self.UI.ty_chbx.isChecked(),
                     'tz':self.UI.tz_chbx.isChecked(),
                     'rx':self.UI.rx_chbx.isChecked(),
                     'ry':self.UI.ry_chbx.isChecked(),
                     'rz':self.UI.rz_chbx.isChecked(),
                     'sx':self.UI.sx_chbx.isChecked(),
                     'sy':self.UI.sy_chbx.isChecked(),
                     'sz':self.UI.sz_chbx.isChecked()
                    }
        
        objs = cmds.ls(sl=True)
        if not objs:
            print 'no object selected...'
            return
            
        for obj in objs:
            for ch in chbxState:
                attr = '.'.join([obj,ch])
                cmds.setAttr(attr,lock=False)
                if chbxState[ch]:
                    cmds.setAttr(attr,lock=True)

    ## doItした上でclose
    def doIt_close(self):
        self.doIt()
        self.close()



#------------------------------------------------------------------------------ 
## GUIの起動
def main():
    app = QtGui.QApplication.instance()
    ui = GUI()
    ui.show()
    
    return ui
 
 
if __name__ == '__main__':
    main()
 
#-----------------------------------------------------------------------------
# EOF
#-----------------------------------------------------------------------------

チェックボックスが入ってるかどうかを取得して、入ってたらそのチャンネルをロックする、という例です。

実行

import sys
sys.path.append('path/to/your/scripts')

import mayapyAdCl

myWin = mayapyAdCl.main()

.uiおよび.pyを置いたところにパスを通して、
importして実行します。

備考

QApplication

元記事はpython.exeに投げる内容ですが、ここではMaya上での実行を考えているため、QApplicationのインスタンスを取る箇所を変えておく必要があります。

具体的には…

app = QtGui.QApplication(sys.argv)
# Error: A QApplication instance already exists.
# Traceback (most recent call last):
#   File "<maya console>", line 1, in <module>
# RuntimeError: A QApplication instance already exists. # 

このようなエラーが起きてしまうので

app = QtGui.QApplication.instance()

こういう風に書き換えておきます。
あわせてsys.exit(app.exec_())もここでは削除するかコメントアウトしておきましょう。

mayaMixin

作ったウィンドウをMayaのメインウィンドウに親子付けしておかないと、
後ろに隠れるシャイな子になってしまいます。

かつてはshibokenをつかってポインタ取って云々というしきたりがありましたが、
mayaMixinを活用すると、その記述を省けます。

from maya.app.general.mayaMixin import MayaQWidgetBaseMixin

インポートして

class GUI(MayaQWidgetBaseMixin, QtGui.QMainWindow):

継承します。

参考:
http://help.autodesk.com/view/MAYAUL/2017/JPN/?guid=__files_GUID_66ADA1FF_3E0F_469C_84C7_74CEB36D42EC_htm

mainのreturn

main関数にreturn uiというのを足しています。
これを受け取っておくと、UI作成中のデバッグが捗るかと思います。

close

ウィンドウを閉じるのには
QMainWindowにもとからあるメソッドを使います。

setSignals関数とdoIt_close関数内で使っていますが、
ほかのUI要素を self.UI.tx_chbx などとしているのと同じノリで
うっかりself.UI.close() と書かないよう注意してください。

おわりに

元記事のステキさあっての補足であります。

どなたかのお役に立てれば幸いです。
(動かない等へんなところがあれば教えてください。。。)

次はmono_gさんの記事 「Mayaのマテリアルのこねこね」 です。
http://qiita.com/mono-g/items/520f4967356456eb4cc5
※『次は』といいつつmono_gさんの記事のほうが先に公開されてますが!大遅刻すみません(汗

26
25
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
26
25

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?