2013/05/21

[maya] スプラッシュスクリーンを作ろう

pymel や Qt 使って GUI 作るとインポートに時間かかって初回起動すごい遅いですよね...
バグってんじゃないかと思うくらいです

そこで今回はその待ち時間解消のためのスプラッシュスクリーンを maya で作ってみた例です



スプラッシュスクリーンのクラスを作る


まずはスプラッシュスクリーンを作る部分から
インポートの軽い cmds でがんばって作ります

splashScreen.py
# -*- coding: utf-8 -*-

import os
import maya.cmds as cmds
import maya.mel as mel

## スクリプトの置いてある位置
CURRENT_DIR = os.path.dirname(__file__)
## 画像フォルダ
IMAGE_DIR = os.path.join(CURRENT_DIR, 'images')

#-----------------------------------------------------------------------------
## スプラッシュスクリーン作るクラス
class SplashScreen():

    _windowName = 'splashScreenWindow'
    # スプラッシュスクリーンの画像のサイズ
    _windowWidth = 400
    _windowHeight = 176
    _windowHeight += 16     # 文字の分追加する

    ## 初期化
    def __init__(self):
        self.checkUI()
        self.window = self.createWindow()
        self.createUI()

    ## ウインドウの作成
    def createWindow(self):
        window = cmds.window(self._windowName, titleBar=False, sizeable=False)
        return window

    ## UIの中身を作成
    def createUI(self):
        cmds.setParent(self.window)
        column = cmds.columnLayout(adjustableColumn=True)
        imagePath = os.path.join(IMAGE_DIR, 'splashScreen.png')
        self.image = cmds.image(image=imagePath)
        self.text = cmds.text(label='Loading please wait...', align='left')

    ## 中心に配置されるように表示する上端、左端の位置を取得
    def getshowPosition(self):
        mayaWindow = mel.eval('string $temp = $gMainWindow;')
        mwWidth = cmds.window(mayaWindow, query=True, width=True)
        mwHeight = cmds.window(mayaWindow, query=True, height=True)
        x = (mwWidth - self._windowWidth) / 2
        y = (mwHeight - self._windowHeight) / 2
        return x, y

    ## 既存UIの削除
    def checkUI(self):
        if cmds.window(self._windowName, exists=True):
            cmds.deleteUI(self._windowName)

    ## スプラッシュスクリーンを削除
    def delete(self):
        cmds.deleteUI(self._windowName)

    ## 表示する文章を設定
    def setText(self, text):
        cmds.text(self.text, edit=True, label=text)
        cmds.refresh()

    ## GUIの表示
    def show(self):
        cmds.showWindow(self.window)

        # ウインドウをリサイズ
        cmds.window(self.window, edit=True, width=self._windowWidth)
        cmds.window(self.window, edit=True, height=self._windowHeight)
        x, y = self.getshowPosition()
        cmds.window(self.window, edit=True, leftEdge=x)
        cmds.window(self.window, edit=True, topEdge=y)
        cmds.refresh()


#----------------------------------------------------------------------------
これを実行すると、mayaのど真ん中にこんな感じのタイトルバーも何にも無いウインドウが出来ます

window 関数で titleBar=False なんてフラグ指定したの初めてです笑


この例だと、スクリプトがある位置に imagesフォルダがあって、
その中に splashScreen.png という画像があるテイです




本体のUIクラスを作る


次はメインのUIです
この例では空っぽですが、pymel でがっつり書きなぐります
さっきのとは別のスクリプトファイルとして作ります

GUI.py
# -*- coding: utf-8 -*-

import os
import pymel.core as pm

#-----------------------------------------------------------------------------
## メインのGUI
class MainGUI(object):

    _windowName = 'mainGUIWindow'
    _windowTitle = 'Main GUI'

    def __init__(self):
        self.checkUI()
        self.window = self.createWindow()

    ## ウインドウの作成
    def createWindow(self):
        window = pm.window(self._windowName)
        window.setTitle(self._windowTitle)
        return window

    ## UIの中身を作成
    def createUI(self):
        pm.setParent(self.window)
        column = pm.columnLayout(adjustableColumn=True)

        ''' ここにUIの要素が入る
        '''

    ## 既存UIの削除
    def checkUI(self):
        if pm.window(self._windowName, exists=True):
            pm.deleteUI(self._windowName)

    ## GUIの表示
    def show(self):
        self.window.show()

#-----------------------------------------------------------------------------



スプラッシュ→本体 という流れを作る


スクリプトファイルも複数だし、画像データもあるのでモジュール化してしまいましょう
ブログ用にはしょるために __init__.py にいろいろ書いてますが、
あまりよろしくない気がするので実践では別に分けたほうがいいと思います

__init__.py
# -*- coding: utf-8 -*-

import time

import splashScreen
reload(splashScreen)

def main():
    # スプラッシュスクリーンを表示
    Splash = splashScreen.SplashScreen()
    Splash.show()
    Splash.setText('Loading please wait...')

    # 待ってる感を出すのに sleep を入れているが
    # 本来はいらないので消しましょう
    time.sleep(5)

    # 表示の重いGUIを実行
    # import分などはここに書く
    import GUI
    reload(GUI)
    ui = GUI.MainGUI()
    ui.show()

    # スプラッシュスクリーンを削除
    Splash.delete()

#-----------------------------------------------------------------------------
ここまで出来たら、 __init__.py GUI.py splashScreen.py images\splashScreen.png を
splashScreen などのフォルダにまとめて python モジュール化します

このフォルダを python パスの通っているところに置いて
以下のように実行すると、
import splashScreen
reload(splashScreen)
splashScreen.main()
スプラッシュスクリーンがまず表示される
  ↓
pymel のインポートなどで待ちが発生する
  ↓
本体のGUIが表示される
  ↓
スプラッシュスクリーンが消える

という一連で表示されていきます




まとめ


実際にやってみると分かると思うのですが、スプラッシュスクリーンがあるのと無いのとでは
待てる時間が結構変わるので、良かったら試してみてください




0 件のコメント:

コメントを投稿