7

Autodesk Maya でツールを開発しています。私が構築するツールの多くには、アニメーターやモデラーが使用するためのシンプルなウィンドウ GUI があります。これらの GUI には、多くの場合、基本的なウィンドウで通常表示されると予想されるものが含まれています。ラベル、リスト、メニュー、ボタン、テキストフィールドなど。ただし、利用可能なツールで構築できる UI の複雑さには制限があり、特に利用可能なウィジェットの種類には制限があります。

ListView (グリッド)、ツリーなど、より高度な wxPython ウィジェットの使用に興味があります。これには、完全な wxFrame (ウィンドウ) を使用して UI 全体を表示することが含まれます。これは、基本的に、ウィンドウがもはや存在しないことを意味します。マヤと結ばれます。大した問題ではありませんが、Maya が最小化されている場合、ウィンドウがそれに追随しません。

テストとして tkinter を使用して以前にこのようなことを試したことがありますが、独自のスレッドで実行するには MainLoop が必要であることがわかりました。これは論理的ですが、私の場合、Maya 自体のスレッドと競合するため、基本的にウィンドウが閉じられるまで Maya がハングアップします。これは、MEL であれ Python であれ、Maya がすべてのスクリプトをメインの Maya GUI が共有する単一のスレッドで実行するためです。これは、別のスクリプトが同じオブジェクトに対して作業を行おうとしているときに、あるスクリプトがオブジェクトを削除することを防ぐためです。

wxPython には、これと同じ「メインループ」方法論があります。Maya 内で機能するように回避する方法があるかどうか疑問に思っていますか?

4

3 に答える 3

2

これが密接な関係があるかどうかはわかりませんが、PyQt が Maya 内で非常に人気があることが判明しました。Maya を介して新しいスレッドループを作成し、その中で実行する手法は、こちらまたはこちら(ソース コードで説明さています) で試すことができます。Maya には、内部に QApplication を含む新しいスレッド オブジェクトを設定するモジュールが含まれているようです。

def initializePumpThread():
    global pumpedThread
    global app
    if pumpedThread == None:
        app = QtGui.QApplication(sys.argv)
        pumpedThread = threading.Thread(target = pumpQt, args = ())
        pumpedThread.start()

次に、Qt イベントを処理する関数を設定します。

def pumpQt():
    global app
    def processor():
        app.processEvents()
    while 1:
        time.sleep(0.01)
        utils.executeDeferred( processor )

おそらく wxPython でも同様のことができます。(utils.executeDeferred は Maya の関数です。) wxPython wiki でノンブロッキング GUIを作成する方法を確認してください。processEvents() の代わりに、イベント ループを設定し、上記の (できれば名前が変更された?) pumpQt 関数内の「保留中」イベントをチェックする必要があります。(wxPython ソースには、MainLoop のPython 実装が含まれています。) これはおそらく app.Yield() 関数を介して行う必要がありますが、よくわかりません。

def pumpWx():
    global app
    def processor():
        app.Yield(True)
    while 1:
        time.sleep(0.01)
        utils.executeDeferred( processor )

def initializePumpThread():
    global pumpedThread
    global app
    if pumpedThread == None:
        app = wx.App(False)
        pumpedThread = threading.Thread(target = pumpWx, args = ())
        pumpedThread.start()

wxPython ドキュメントは、SafeYield()が優先されることを示しています。繰り返しますが、これは最初のステップのように思えますが、恐ろしくクラッシュするだけでなく、うまくいくかどうかはわかりません。(何をしたいのかについてwxPython メーリング リストでいくつかの議論がありますが、それは以前の wx のいくつかのマイナー バージョンからのものです。) また、さまざまなフォーラムで、この手法がキーボード入力で問題を引き起こすという指摘があります。次のことも試してみてください。

def processor():
  while app.Pending(): app.Dispatch()

イベントの現在のリストを処理します。

幸運を!

于 2008-12-30T02:48:01.443 に答える
0

最善の方法は、必要なもので QWidget を作成し、C++ API を介して MPxCommand 内から使用することです。そうすれば、scriptedPanels を介して完全なカスタム エディタを Maya に挿入することもできます。

しかし、Python に縛られている場合は、pyQt が最適です。

于 2015-05-14T21:18:00.333 に答える
0

すべてのイベントチェーンと再描画キューを処理する必要があるため、GUI のメインループを回避する方法があるかどうかはわかりません。

ただし、パイプやセマフォなど、プロセス間通信の手段はいくつかあります。おそらく、Maya 拡張機能を実際のプラグインに分割し、Maya にタイトにし、GUI 用の別のアプリケーションにするオプションです。これら 2 つは、このような手段を使用して、プラグインと GUI の間でモデル情報を通信および交換できます。ただし、アプリケーションが非常に複雑になるため、このアプローチを本当にお勧めできるかどうかはわかりません。

インタラクティブな Python シェルである IPython を見ることができます。このシェルの開発チームは、wxPython との統合に力を入れています。イベント ループを中断し、それにフックして独自の処理を実行する何らかの方法があります。

于 2008-12-29T19:41:38.260 に答える