Last active
May 2, 2024 09:44
-
-
Save 44hero/f1d9c156f14065e6a6a6453411de0fa6 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# 標準ライブラリ ################################################################# | |
from functools import partial | |
from pprint import pprint | |
from typing import Tuple, List | |
# サードパーティライブラリ ######################################################### | |
# from maya import OpenMayaUI, cmds | |
from PySide2.QtWidgets import (QApplication, QComboBox, QGridLayout, | |
QMainWindow, QWidget, QHBoxLayout, QVBoxLayout, | |
QPushButton, QAction, QFrame, QLabel, | |
QSpacerItem, QSizePolicy, | |
) | |
from PySide2.QtGui import QIcon | |
from PySide2.QtCore import Qt | |
# ローカルで作成したモジュール ###################################################### | |
# basic_configuration(基本構成) | |
from .config import SPACE, TITLE, VERSION | |
# shiboken2 独自モジュール | |
from ..qt import getMayaWindow # 利用時は、getMayaWindow() | |
from ..pyside2IniFileSetting import IniFileSetting | |
# 汎用ライブラリー の使用 #################################################### start | |
from ...lib.message import message | |
# from ...lib.message_warning import message_warning | |
# 汎用ライブラリー の使用 #################################################### end | |
class Tpl4PySide2_Type1_View(QMainWindow): | |
u""" < GUIウィンドウを作成するための Viewクラス です > | |
:: | |
UIを作成するためのメソッドや、UIの更新を行うためのメソッドを実装します。 | |
GUIウィンドウを作成するための PySide2 コードが含まれます。 | |
Viewクラスのコンストラクターは、Modelオブジェクト への参照を受け取ります。 | |
View クラスは GUIウィンドウ を作成し、そのウィンドウ内の要素を更新するためのメソッドを提供します。 | |
.. note:: | |
従来の、 | |
UIのサイズを保存する、 | |
`windowPrefs.mel` | |
Maya のさまざまな呼び出しに存在する変数を設定および照会できる、プリファレンスの一部である、 | |
maya独自規格{optionVar」 | |
以上2つの Maya専用の 保存参照規格 からの、代替え案として、 | |
PySide2 規格 の .iniファイル | |
を使用したやり方です。 | |
:: | |
ファイルの保存先には、運用ルールが必要です。。。 | |
ここでは、「マイドキュメント/maya/versionNumber」に | |
フォルダ「f'{prefix}_{commonName}'」を作り、 | |
設定ファイルが保存されていくようにしています。 | |
ファイル名はクラス変数にして、継承したクラスで変更できるようにします | |
基本となるUI構成で不可欠となる要素 8つ は以下です | |
- <UI要素 1>. UIを、Maya window 画面の前面にする | |
- <UI要素 2>. UIの title設定 と、新規での ポジションとサイズ設定 | |
- <UI要素 3>. UI設定の 保存 と 復元 の機能を 何らかで実現する | |
- <UI要素 4>. UI設定の 保存 と 復元 の機能 | |
Note): オリジナルメソッド {saveSettings」, 「restore」 で実現 | |
- <UI要素 5>. UIの 重複表示の回避 | |
- <UI要素 6>. UIの 見た目の統一 | |
- <UI要素 7>. -Pyside2特有事項- UI の close 時に delete されるようにする | |
- <UI要素 8>. UIの window name (objectName) 設定 | |
###### | |
基本となるUI要素は以下の 6つ | |
- UI-0. 重複しないウインドウ | |
- UI-1. commonメニュー | |
- UI-2. メインLayout + common情報 + 追加オプション | |
- UI-3. ボタンLayout + common底面ボタン3つ | |
- UI-4. OptionVar を利用したパラメータ管理 | |
- (5. スクリプトベースコマンド入力への対応) | |
構成要素である以下の1群のみ一部ここ View へ移動 | |
- 1. UI-1. メニュー コマンド群 | |
###### | |
""" | |
# initialize(初期化関数)コンストラクタです。 | |
# ここで定義されたインスタンス変数は、他のメソッドで上書き・参照が出来ます。 | |
# 当該window を Maya window 画面の前面にする設定 も行っています | |
def __init__(self, _model, parent = None, flags = Qt.WindowFlags()): | |
u""" < initialize(初期化関数)コンストラクタ です > | |
:: | |
ここで定義されたインスタンス変数は、他のメソッドで上書き・参照が出来ます。 | |
基本となるUI構成で不可欠となる要素 8つ の内、以下 2つ を実行しています | |
- <UI要素 1>. UIを、Maya window 画面の前面にする | |
- <UI要素 3>. UI設定の保存と復元 の機能を 何らかで実現する | |
.iniファイルを利用した、 | |
- windowUIの、ポジションとサイズ、 | |
- 他必要箇所となる 入力フィールドの要素、 | |
の、保存と復元 の機能を有効にする | |
""" | |
# <UI要素 1>. | |
# 当該window を Maya window 画面の前面に ######################################## start | |
if parent is None: | |
parent = getMayaWindow() | |
# 当該window を Maya window 画面の前面に ######################################## end | |
super(Tpl4PySide2_Type1_View, self).__init__(parent, flags) | |
self.model = _model | |
self.controller = None | |
# ###################################################################### | |
self.title = TITLE # <- window の title名 | |
self.space = SPACE | |
self.version = VERSION | |
self.underScore = '_' | |
self.win = TITLE + '_ui' # <- window へ objectName | |
# 不変要素な、4つ 且つ typeがint であることを明記 | |
self.size: Tuple[int] = (500, 300, 210, 270) # x, y, width, height | |
self.bgc = "background-color:gray; color: white" | |
self.infoSummary = (u'XXXのツール\n' | |
u'の バージョンYYY(ZZZ版) です。') | |
self.infoDetail = u'AAAのBBBをCCCしました。' | |
# ###################################################################### | |
# <UI要素 3>. | |
# コンストラクタのまとまり1_.iniファイル 設定 | |
self.constructorChunk1_iniFileSetting() | |
# コンストラクタのまとまり2_.iniファイルのパラメーター 設定 | |
self.constructorChunk2_iniFileParam() | |
... | |
# コンストラクタのまとまり1_.iniファイル 設定 | |
def constructorChunk1_iniFileSetting(self): | |
u""" < コンストラクタのまとまり1_.iniファイル 設定 > | |
###################### | |
""" | |
# .iniファイルの設定 ########################################################### start | |
self.iniFS = IniFileSetting(self.title) # pyside2IniFileSetting モジュール | |
filename, _settings = self.iniFS.iniFileSetting() # .iniファイルの設定 メソッド | |
self.filename = filename | |
self._settings = _settings | |
# .iniファイルの設定 ########################################################### end | |
# コンストラクタのまとまり2_.iniファイルのパラメーター 設定 | |
def constructorChunk2_iniFileParam(self): | |
u""" < コンストラクタのまとまり2_.iniファイルのパラメーター 設定 > | |
###################### | |
""" | |
# .iniファイルのパラメーター設定 ##################################### start | |
self.iniFileParam = {'geo_iFP': 'geometry', | |
} | |
# self.od = OrderedDict(self.iniFileParam) # 順序付き辞書 定義 | |
# .iniファイルのパラメーター設定 ##################################### end | |
# オリジナルメソッド | |
# 重複ウィンドウの回避関数 | |
def _duplicateWindowAvoidFunction(self, winName: str): | |
u""" < 重複ウィンドウの回避関数 です > | |
オリジナルメソッド | |
:param str winName: self.win # window ui name に相当します | |
""" | |
widgets = QApplication.allWidgets() | |
for w in widgets: | |
if w.objectName() == winName: | |
# w.close() | |
w.deleteLater() | |
# オリジナルメソッド | |
# Window基本設定 | |
def _windowBasicSettings(self): | |
u""" < 当該window の、基本設定 をいっぺんに行う 関数 です > | |
オリジナルメソッド | |
.. note:: | |
- set window title と 新規のポジションとサイズ設定 : <UI要素 2>. | |
- set window name : <UI要素 8>. | |
はここで行っています | |
基本となるUI構成で不可欠となる要素 8つ の内、以下 5つ を実行しています | |
- <UI要素 2>. UIの title設定 と、新規での ポジションとサイズ設定 | |
- <UI要素 5>. UIの重複の回避 | |
- <UI要素 6>. UIの見た目の統一 | |
- <UI要素 7>. -Pyside2特有事項- UIのclose時にdeleteされるようにする | |
- <UI要素 8>. UI window name (objectName) 設定 | |
""" | |
# <UI要素 2>. | |
# UI設定の保存と復元 の機能 ###################################################### start | |
# self.setWindowTitle(self.title[2:] + self.space + self.version) # <- window の title名 設定 | |
self.setWindowTitle(self.title + self.space + self.version) # <- window の title名 設定 | |
# ウィンドウが一度でも作成されているかどうかを確認 | |
# 純粋に初めてのUI作成時: False # 以下を実行 | |
# 次回再度ロード時は: True # ここをスキップし、前回の ポジションとサイズ が復元される | |
if not self.isVisible(): | |
self.setGeometry(*self.size) # 完全に新規にUI作成したときの初期値。アンパック(*)は重要 | |
# UI設定の保存と復元 の機能 ###################################################### end | |
# <UI要素 5>. | |
# UIの 重複表示の回避 ########################################################### start | |
# old style ############################### start | |
# child_list = self.parent().children() | |
# for c in child_list: | |
# # 自分と同じ名前のUIのクラスオブジェクトが存在してたらCloseする | |
# if self.__class__.__name__ == c.__class__.__name__: | |
# c.close() | |
# old style ############################### end | |
self._duplicateWindowAvoidFunction(winName = self.win) # 重複ウィンドウの回避関数 | |
# UIの 重複表示の回避 ########################################################### end | |
# <UI要素 6>. | |
# UIの 見た目の統一 ############################################################# start | |
# Windows用 window の見た目の制御を行います | |
# # type1 | |
# # minimize, maximize, close 有り | |
# self.setWindowFlags(Qt.Window) | |
# # type2 | |
# # minimize のみ有り | |
# self.setWindowFlags(Qt.Window | Qt.WindowMinimizeButtonHint) | |
# type3 | |
# close のみ有り | |
self.setWindowFlags(Qt.Window | Qt.WindowCloseButtonHint) # windowの右上にx印(close)のみ | |
# UIの 見た目の統一 ############################################################# end | |
# self.setUpdatesEnabled(True) # デフォルトでTrueです | |
# <UI要素 7>. | |
# -Pyside2特有事項- UI の close 時に delete されるようにする ###################### start | |
# PySideで作ったGUIは何もしてないと close しても delete はされません。 | |
# windowオブジェクト に `setAttribute` することで close 時に delete されるようになります。 | |
self.setAttribute(Qt.WA_DeleteOnClose) # <- close 時に delete 設定 | |
# -Pyside2特有事項- UI の close 時に delete されるようにする ###################### end | |
# <UI要素 8>. | |
# UIの window name (objectName) 設定 ########################################## start | |
# set window name | |
self.setObjectName(self.win) # <- window へobjectName 設定 | |
# UIの window name (objectName) 設定 ########################################## end | |
# <UI要素 4>. | |
# UI設定の保存と復元 の機能 の 一部 ############################################### start | |
# different style ######################## start | |
# Note: .iniファイルを使用せず、maya独自規格使用時 有効です | |
# 但し、UIに入力フィールドとう存在した場合には、それらはここには含まれず、他のアプローチも必要 | |
# window を close したときのサイズ・位置のみが `windowPrefs.mel` に保存されるようになり、 | |
# 次回 show 時に復元されるようになります。 | |
# self.setProperty("saveWindowPref", True) | |
# different style ######################## end | |
# UI設定の保存と復元 の機能 の 一部 ############################################### end | |
# UIの起動 関数 | |
def createUI(self): | |
u""" < UIの起動 関数 です > | |
""" | |
self._windowBasicSettings() # 当該window の設定をいっぺんに行う 関数 | |
self.controller = self.model.controller # 和えて明示しています。無くてもこのケースでは実行可。 | |
# print('--- createUI, koko') | |
# print(self.ui) | |
# | |
# if self.ui is not None: | |
# self.ui.deleteLater() | |
# 1):############################################################################### | |
# 概要: メインウィンドウ の中央に配置される セントラルウィジェット です | |
# 1): QWidget -Widget- ############################################## -Widget- start | |
self.central_wid = QWidget(self) # セントラルウィジェット | |
self.setCentralWidget(self.central_wid) # 中央に配置 | |
# 1): QWidget -Widget- ############################################## -Widget- end | |
# 1):############################################################################### | |
# Clear existing menu items | |
# self.menuBar().clear() | |
# UI-1. commonメニュー | |
self.commonMenu() # ############################### UI-1. commonメニュー | |
# 2):############################################################################### | |
# 概要: セントラルウィジェット 内の メインレイアウト です | |
# 2): QVBoxLayout -Layout- ########################################## -Layout- start | |
# セントラルウィジェット に 縦のメインレイアウト | |
# を作成し そのウィジェット へ set ############### 作成しただけでは表示されません -Layout- | |
main_vbxLay = QVBoxLayout(self.central_wid) # メインレイアウト | |
# レイアウトの余白を調整 | |
main_vbxLay.setContentsMargins(3, 3, 3, 3) | |
# 2): QVBoxLayout -Layout- ########################################## -Layout- end | |
# 2):############################################################################### | |
# 3):############################################################################### | |
# 概要: メインレイアウト 内には、大フレーム群 と 底面ボタン群 が縦に配置されます | |
# 3.1): 大フレーム群 -Widget- ######################################### -Widget- start | |
# セントラルウィジェット 内に ウィジェット(大フレーム用) | |
# を作成 ###################################### 作成しただけでは表示されません -Widget- | |
self.frame_frWid = QFrame(self.central_wid) # フレームウィジェット(大フレーム用) | |
# フレームウィジェット(大フレーム用) に 縦のレイアウト(大フレーム用) | |
# を作成し そのウィジェット へ set ############### 作成しただけでは表示されません -Layout- | |
self.frame_vbxLay = QVBoxLayout(self.frame_frWid) # レイアウト(大フレーム用) | |
# フレームウィジェット(大フレーム用) を メインレイアウト | |
# に追加 ###################################### 追加して初めて表示されます -表示- | |
main_vbxLay.addWidget(self.frame_frWid) | |
# フレームウィジェット(大フレーム用) を装飾 | |
# 設定を施す ################################### | |
self.frame_frWid.setFrameShape(QFrame.StyledPanel) # 枠のスタイルを設定 | |
# まとまりA | |
# 大フレーム群 に収まっているものです ######################################## start | |
# UI-2. common情報 | |
# 設定を施す ################################### | |
self.commonInformation(frame_layout = self.frame_vbxLay) # ############################ UI-2. common情報 | |
# UI-2. 追加オプションのまとまり | |
# 設定を施す ################################### | |
self.displayOptions(frame_layout = self.frame_vbxLay) # #################### UI-2. 追加オプションのまとまり | |
# 大フレーム群 に収まっているものです ######################################## end | |
# 常に、大フレーム のトップ に順番に配置されるようにするため、垂直スペーサーを追加して間隔を制御 | |
# まとまりA を装飾 | |
# 設定を施す ################################### | |
spacer = QSpacerItem(20, 1, QSizePolicy.Minimum, QSizePolicy.Expanding) | |
self.frame_vbxLay.addItem(spacer) | |
# 3.1): 大フレーム群 -Widget- ######################################### -Widget- end | |
# 3.2): 底面ボタン群 -Layout- ###################################$##### -Layout- start | |
# セントラルウィジェット 内に 水平レイアウト(底面ボタン用) | |
# を 直接 作成 追加 ###################################### 一遍に行えます | |
self.button_hbxLay = QHBoxLayout(self.central_wid) # レイアウト(底面ボタン用) | |
# まとまりB | |
# 底面ボタン群 です ####################################################### start | |
# UI-3. common底面ボタン3つ | |
# 設定を施す ################################### | |
self.commonButtons(self.button_hbxLay) # ######################## UI-3. common底面ボタン3つ | |
# 底面ボタン群 です ####################################################### end | |
# レイアウト(底面ボタン用) を メインレイアウト | |
# に追加 ###################################### 追加して初めて表示されます -表示- | |
main_vbxLay.addLayout(self.button_hbxLay) | |
# 3.2): 底面ボタン群 -Layout- ###################################$##### -Layout- end | |
# 3):############################################################################### | |
self.show() # 最終的にUIを作成 |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment