single UI & parent UI をまとめて実現
■パターン1
- 1つのpythonファイルで完結コーディング の場合
1 pythonファイル
| # -*- coding: utf-8 -*-
# OK: parent UI 実現
# OK: single UI 実現
from PySide2 import QtCore, QtGui, QtWidgets
from maya import OpenMayaUI as omUI
import shiboken2
# parent UI 実現の準備
# OpenMayaUIに、Qtに関する補助機能が用意されています。これはPythonからでも利用できますが、「C++」の
# 「ポインタ※」という機能がPython には無いため、そのままでは使用できません。そこで、C++ で作られた機能
# をPythonから使えるようにしてくれる、PySide付属のモジュール「shiboken」を使用して対応していきます。
# 「shiboken」の中には、「wrapInstance」という機能があり、C++ のポインタの情報をPython で扱えるデータ
# に変換してくれます。コレを使ってポインタからQWidget に変換したデータを、呼び出された場所に「return」を
# 使用して返します。
# 「ポインタ」とは、データがメモリのどこに保存されているか、住所を表すものです。
def getMayaWindow(): # Maya のウィンドウを取得する関数です
"""
Get the main Maya window as a QtGui.QMainWindow instance
@return: QtGui.QMainWindow instance of the top level Maya windows
"""
ptr = omUI.MQtUtil.mainWindow()
if ptr is not None:
return shiboken2.wrapInstance(long(ptr), QtWidgets.QMainWindow)
class testUI(QtWidgets.QDialog):
def __init__(self):
# parent UI
super(testUI, self).__init__(getMayaWindow())
self.setWindowTitle('test UI')
# すでにUIが出来てる場合は削除する #
# MayaのMainWindowの子Windowを取得
child_list = self.parent().children()
for c in child_list:
# 自分と同じ名前のUIのクラスオブジェクトが存在してたらCloseする
if self.__class__.__name__ == c.__class__.__name__:
c.close()
# ------------------------ #
btn = QtWidgets.QPushButton("Hello World")
layout = QtWidgets.QVBoxLayout()
layout.addWidget(btn)
self.setLayout(layout)
def main():
mainWindow = getMayaWindow()
nowExists = mainWindow.findChildren(testUI)
# single UI
# findChildrenで、指定クラスの子を探すのではなく
# 全ての子オブジェクトのクラス名で判定して、同じなら閉じるようにすれば
# reloadしようがScriptEditorで実行しようが問題ない。
for i in nowExists:
i.close()
win = testUI()
win.show()
if __name__ == '__main__':
print(u'{}.py: loaded as script file'.format(__name__))
main()
else:
print(u'{}.py: loaded as module file'.format(__name__))
print(u'モジュール名:{}'.format(__name__)) # 実行したモジュール名を表示する
|
例えば、
lib フォルダ
├ __init__.py
└ qt.py
として、
2 pythonファイル
qt.py
| # -*- coding: utf-8 -*-
# parent UI 実現の準備
from maya import OpenMayaUI, cmds
from PySide2 import QtWidgets, QtCore, QtGui
import shiboken2
# parent UI 実現の準備
# OpenMayaUIに、Qtに関する補助機能が用意されています。これはPythonからでも利用できますが、「C++」の
# 「ポインタ※」という機能がPython には無いため、そのままでは使用できません。そこで、C++ で作られた機能
# をPythonから使えるようにしてくれる、PySide付属のモジュール「shiboken」を使用して対応していきます。
# 「shiboken」の中には、「wrapInstance」という機能があり、C++ のポインタの情報をPython で扱えるデータ
# に変換してくれます。コレを使ってポインタからQWidget に変換したデータを、呼び出された場所に「return」を
# 使用して返します。
# 「ポインタ」とは、データがメモリのどこに保存されているか、住所を表すものです。
def getMayaWindow(): # Maya のウィンドウを取得する関数です
"""
Get the main Maya window as a QtGui.QMainWindow instance
@return: QtGui.QMainWindow instance of the top level Maya windows
"""
ptr = OpenMayaUI.MQtUtil.mainWindow()
if ptr is not None:
widget = shiboken2.wrapInstance(long(ptr), QtWidgets.QMainWindow)
return widget
|
pythonファイル
| # -*- coding: utf-8 -*-
# OK: parent UI 実現
# OK: single UI 実現
from PySide2 import QtCore, QtGui, QtWidgets
from maya import OpenMayaUI as omUI
from lib import qt # shiboken2はここで読み込み
class testUI(QtWidgets.QDialog):
def __init__(self):
# parent UI
super(testUI, self).__init__(qt.getMayaWindow())
self.setWindowTitle('test UI')
# すでにUIが出来てる場合は削除する #
# MayaのMainWindowの子Windowを取得
child_list = self.parent().children()
for c in child_list:
# 自分と同じ名前のUIのクラスオブジェクトが存在してたらCloseする
if self.__class__.__name__ == c.__class__.__name__:
c.close()
# ------------------------ #
btn = QtWidgets.QPushButton("Hello World")
layout = QtWidgets.QVBoxLayout()
layout.addWidget(btn)
self.setLayout(layout)
def main():
mainWindow = qt.getMayaWindow()
nowExists = mainWindow.findChildren(testUI)
# single UI
# findChildrenで、指定クラスの子を探すのではなく
# 全ての子オブジェクトのクラス名で判定して、同じなら閉じるようにすれば
# reloadしようがScriptEditorで実行しようが問題ない。
for i in nowExists:
i.close()
win = testUI()
win.show()
if __name__ == '__main__':
print(u'{}.py: loaded as script file'.format(__name__))
main()
else:
print(u'{}.py: loaded as module file'.format(__name__))
print(u'モジュール名:{}'.format(__name__)) # 実行したモジュール名を表示する
|
■パターン2
最終更新日:
2024年4月18日 09:56:45