[Python] MayaのUI作成が面倒くせーーーーー

MayaのUI作成に関して僕は結構肯定派なのですが、
最近ではかつてよりもちょくちょく大きなサイズのものを書いているので、以前と比べると比較にならないほど面倒です。


例えばボタンを押したら実行されるコールバック関数的なものを考える際、
例えばtextFieldとradioButtonGrpから値をとってこようと考えます。
とりあえず思いつくのは、コントロールの名前を渡してこんな感じで値を取る方法。

tx = cmds.textField(tf_xxx, q=True, tx=True)
sl = cmds.radioButtonGrp(rbg_xxx, q=True, sl=True)

今までは大概こんな感じでやってたんですが、だんだん面倒臭くなって来ました・・・!!

例えばこんな感じで取得出来るといいんだけどなぁ。

tx = tf_xxx.get()
sl = rbg_xxx.get()

これなら楽。超楽。
この場合、tf_xxxとかUIコントロールクラスのインスタンスになんですよね、きっと。
でもコレだと何が返ってくるかわかんないじゃん!とも思う。

じゃあ、あらかじめ何を返すか決めとけばいいんじゃない?と考える。
例えば、

tf_xxx = TextField(tx='tmptxt')
tf_xxx.setReturnValue('text')
rbg_xxx = RadioButtonGrp(l='tmpradio', nrb=2, la2=['a', 'b'], sl=1)
rbg_xxx.setReturnValue('index')

こんな感じ?

一般的にはそんなことせずに、テキストならgetText()、インデックスならgetIndex()とかなんだろうなぁ、と思ったりもする。
でも、例えば全部同じインターフェイスでアクセスできると、コントローラオブジェクトを全部配列に突っ込んで、

values = {}
for ctl in ctls:
    values[ctl.name] = ctl.get()

みたいなことが出来たりして、かなりいろいろスッキリするんじゃないかなぁ、なんて思う。

あ、↑のをやりたいだけなら、こんなのもあるか。

tf_xxx = TextField(tx='tmptxt')
tf_xxx.get = tf_xxx.getText
rbg_xxx = RadioButtonGrp(l='tmpradio', nrb=2, la2=['a', 'b'], sl=1)
rbg_xxx.get = rbg_xxx.getIndex

つまりメンバ関数の上書き。
こういう書き方が許されていたかは未確認です。
あ、でも直接上書きよりは、上書きされましたよ情報を持たせたいので、何か関数通してやったほうが良いか、も、ね。

つーかそこまでアイディアあるならフレームワークでも作るべき?
結局コントロールから情報を手軽に取得できたらいいなぁ、っていうだけの話なんですが。

なんか良い方法あればいいんだけど、無ければ作るしかないかな、と思ったり。
次にUI作る必要が出来たら、サイズによっては作る必要出てくるかも。
うぇーーーっ。

ってこういうことを考えても実現出来なかったMEL時代とはエラい違いだなぁ、と実感しています。
すげぇよPython。

「[Python] MayaのUI作成が面倒くせーーーーー」への8件のフィードバック

  1. MayaのPythonはMELやAPIの薄いwrapなんで一部の人に嫌われてる所以です。個人的にはドキュメント別個に管理する労力が半端じゃないので仕方がないのかなあとも思いますが。自分でクラスを作って思い通りのインターフェイスを作ってる所もあります、適当ですがこんな感じ。

    class myCtrl(object):
    def __init__(self, ctrl):
    self.ctrl = ctrl
    def get(self):
    raise NotImplementedError

    class myTextField(myCtrl):
    def __init__(self, tf):
    super(myCtrl, self).__init__(tf)
    def get(self):
    return cmds.textField(self.ctrl, q=True, tx=True)

  2. >hohehohe2さん
    > MayaのPythonはMELやAPIの薄いwrapなんで一部の人に嫌われてる所以です。
    嫌ってますwww
    でも仰る通り、大変な労力だと言うのもわかるので、こういう作りなのもまぁまぁ、、とは思うんですが、他のパッケージのPythonAPI見てると、やっぱりうーんって思ってしまいます・・・
    MELよりもOpenMayaの方が、元々C++なだけあってオブジェクト指向な感じだとは思うんですが、スクリプトの中でフルにそっち使っちゃうのもそれはそれで非常に面倒ですし、、

    > 自分でクラスを作って思い通りのインターフェイスを作ってる所もあります
    やっぱりそうなりますよね。
    ある程度そういうの作った方が良いかなぁなんて考えてます。
    サンプルのソース、非常に参考になります!
    が、一つお聞きしていいですか?
    myCtrlの方でobjectを継承してるんですが、これって何か意味有るんですか?
    現状僕は、

    class myCtrl:
      …

    と宣言しちゃってるんですが、何か違いってあるんですかね。
    よろしくどうぞ。

  3. > それはそれで非常に面倒ですし、、
    > ある程度そういうの作った方が良いかなぁなんて考えてます。

    スクリプトは他の会社と共有したりあんまりしないんで別に構わないと思いますが、なにせ作るのが面倒ですよねー、適当に作るとバグの元になるし。

    > 他のパッケージのPythonAPI見てると、やっぱりうーんって思ってしまいます・・・

    HOMいいですよね。

    > が、一つお聞きしていいですか?

    new style classと言ってPython2.2から採用されたもので、object継承するかどうかでオブジェクト内部の実装が大違いになるんです、外見は違わないように似せているんでそんなに変わらないんですが。具体的にはobjectなしのものはclass-instanceとは別の概念としてtypeというものがPythonの言語実装の為にあったんですが(「classオブジェクトはclassobjタイプ、3.14はfloatタイプ」というように)new style classはclassとtypeが統一された、って言語作ってる人が一番うれしいことでユーザーはそんなに・・・って意見が多いですがnew style classでのみ使える機能もあるんで自分はこっちに統一してます。利点の一つはpropertyが使えるようになることです。

  4. >hohehohe2さん
    > なにせ作るのが面倒ですよねー、適当に作るとバグの元になるし。
    腰が重いのはこれが一番の原因ですね、、
    適当に作れるなら作ってもいいとは思うんですが、、
    そういうわけにも、、

    > new style class~
    あぁぁぁぁぁ、これがそうなんですか。
    なんか存在だけは知ってたんですが、まぁいいか、と思ってスルーしてました・・・w
    非常に興味あるので、自分でももうちょい調べてみます。
    大変参考になりました。ありがとうございます!

  5. 自分のスクリプト内に似たようなことをしてる部分があったので、改造して簡易的なUIコントロールクラスを作ってみました。大量にevalがあってcode的にはキモイですけど。
    以下の自前のwebサイトにcodeを貼り付けておきました。

    http://www.mayapython.com/viewtopic.php?f=6&t=12

    こんな感じで使えます。
    tx = UiCtrl(“mc.textField(‘textFieldName’, text=’text’)”)
    print tx.get()
    tx.set(‘newText’)

    get や set する値の種類をUIコントロールごとに固定しちゃってるんで、ちょっと微妙ですが・・・

    あとUiCtrl Classに渡すのがstringってのもいやだったんですが、UIコントロールの名前からタイプを判別する簡単な方法が見つからなかったので、仕方なくそうなっています。

  6. > inagakiさん
    おっ、さすがです。
    コード拝見します。

    にしてもなんというURLwww < mayapython.com

    なるほど。stringぶった切って判別してるんですね。
    eval多くなるのは確かにちょっと嫌ですが、でもコードとしてはさっくり書けていい感じですね!

    そしてこれ見てて疑問に思った点があるんですが、質問してもいいですか?
    本題とは違っちゃうんですが、、、

    UiCtrlの中で使っている関数(setCtrlsValue, getCtrlsValue)はクラスメソッドじゃないみたいなんですが、これって何か理由があるんですか?

    よろしくおねがいしますーっ。

  7. setCtrlsValueとgetCtrlsValueはもともと別のスクリプトで使ってた関数だったので、そのまま関数として使っただけです。別にUiCtrlクラスのメソッドにしてもよかったんですよ。
    ルームメイトにも同じこと聞かれて、やっぱメソッドにしとけば良かったかなと思いつつも、自分は他でも使ってるし関数でいいかなと判断しました。

    さすがにすべてのUIコントロールでちゃんと動作するかチェックしたわけではないので、問題なく使えるかは少し微妙なところです。(笑)

  8. >inagakiさん
    > もともと別のスクリプトで使ってた関数だった~
    あーーー、なるほど。納得しました。
    ありがとうございますーっ。

コメントを残す

メールアドレスが公開されることはありません。