使用外部GUI庫在Autodesk Maya中創建用戶界面

[英]Using external GUI libraries to make user interfaces in Autodesk Maya


I develop tools in Autodesk Maya. Many of the tools I build have simple windowed GUIs for the animators and modellers to use. These GUIs often contain what you'd normally expect to see in any basic window; labels, lists, menus, buttons, textfields, etc. However, there are limitations to the complexity of the UIs you can build with the available tools, specifically in the types of available widgets.

我在Autodesk Maya中開發工具。我構建的許多工具都有簡單的窗口GUI,供動畫師和建模人員使用。這些GUI通常包含您通常希望在任何基本窗口中看到的內容;標簽,列表,菜單,按鈕,文本字段等。但是,使用可用工具構建的UI的復雜性存在限制,特別是在可用小部件的類型中。

I'm interested in using some of the more advanced wxPython widgets such as the ListView (grid), Tree, etc. This would involve using a complete wxFrame (window) to display the whole UI, which would essentially mean that window would no longer be tied to Maya. Not a deal breaker, but it means when Maya is minimized, the window won't follow suit.

我有興趣使用一些更高級的wxPython小部件,如ListView(網格),樹等。這將涉及使用完整的wxFrame(窗口)來顯示整個UI,這實際上意味着窗口將不再被綁在瑪雅身上。不是交易破壞者,但這意味着當Maya被最小化時,窗口將不會跟隨。

I've tried something like this before with tkinter as a test, but found that it needed a MainLoop to run in its own thread. This is logical, but in my case, it conflicts with Maya's own thread, essentially making Maya hang until the window is closed. This is due to the fact that Maya runs all scripts, be they MEL or Python, in a single thread that the main Maya GUI shares. This is to prevent one script from, say, deleting an object while another script is trying to do work on the same object.

我之前嘗試使用tkinter作為測試,但發現它需要MainLoop才能在自己的線程中運行。這是合乎邏輯的,但在我的情況下,它與Maya自己的線程沖突,實際上使Maya掛起,直到窗口關閉。這是因為Maya在主Maya GUI共享的單個線程中運行所有腳本,無論是MEL還是Python。這是為了防止一個腳本在另一個腳本嘗試對同一個對象進行操作時刪除一個對象。

wxPython has this same "mainloop" methodolgy. I'm wondering if there's any way around it so that it can work within Maya?

wxPython有同樣的“mainloop”方法。我想知道是否有任何解決方法,以便它可以在Maya中工作?

3 个解决方案

#1


I'm not sure if this is germane, but some googling turns up that PyQt is pretty popular inside of Maya. You could try the technique here or here (explained here with source code) of creating a new threadloop via Maya and executing inside of that. It seems Maya has a module included that sets up a new thread object, with a QApplication inside it:

我不確定這是否密切相關,但是一些谷歌搜索結果表明PyQt在Maya中很受歡迎。您可以嘗試通過Maya創建新的threadloop並在其中執行此處或此處的技術(此處使用源代碼解釋)。似乎Maya有一個模塊,它包含了一個新的線程對象,里面有一個QApplication:

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

and then sets up a function to process the Qt events:

然后設置一個函數來處理Qt事件:

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

You can probably do something similar with wxPython as well. (utils.executeDeferred is a Maya function.) Be sure to check out how to create a non-blocking GUI on the wxPython wiki. Instead of processEvents(), you'll want to set up an event loop and check for "Pending" events inside the (hopefully renamed?) pumpQt function above. (The wxPython source has a Python implementation of MainLoop.) Likely this should be done through the app.Yield() function, but I'm not sure.

你也可以用wxPython做類似的事情。 (utils.executeDeferred是一個Maya函數。)請務必查看如何在wxPython wiki上創建非阻塞GUI。您需要設置一個事件循環並檢查上面(希望重命名的?)pumpQt函數中的“Pending”事件,而不是processEvents()。 (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()

The wxPython docs indicate SafeYield() is preferred. Again, this seems like it could be a first step, but I'm not sure it will work and not just crash horribly. (There's some discussion about what you want to do on the wxPython mailing list but it's from a few minor versions of wx ago.) There is also some indication in various forums that this technique causes problems with keyboard input. You might also try doing:

wxPython文檔表明SafeYield()是首選。再次,這似乎可能是第一步,但我不確定它會起作用,而不僅僅是崩潰可怕。 (有一些關於你想在wxPython郵件列表上做什么的討論,但是它來自wx之前的幾個小版本。)在各種論壇中也有一些跡象表明這種技術會導致鍵盤輸入問題。您也可以嘗試:

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

to deal with the current list of events.

處理當前的事件列表。

Good luck!

#2


I don't know if there is a way around a mainloop for the gui, since it is needed to handle all event chains and redraw queues.

我不知道gui的主循環是否有辦法,因為它需要處理所有事件鏈和重繪隊列。

But there are several means of inter-process communication, like pipes or semaphores. Maybe it is an option to split your Maya extension into the actual plugin, being tight into maya, and a separate application for the gui. These two could use such means to communicate and exchange model information between plugin and gui. I'm not sure, however, if I can really recommend this approach because it very much complicates the application.

但是有幾種進程間通信方式,比如管道或信號量。也許這是一個選項,可以將Maya擴展分成實際的插件,緊密分為maya,以及單獨的gui應用程序。這兩個可以使用這種方法在插件和gui之間進行通信和交換模型信息。但是,我不確定是否可以真正推薦這種方法,因為它使應用程序變得非常復雜。

You could have a look at IPython, an interactive Python shell, whose dev team has put some effort into integrating it with wxPython. They have some way of interrupting the event loop and hooking into it to do their own stuff.

你可以看看IPython,一個交互式的Python shell,它的開發團隊已經付出了一些努力將它與wxPython集成。他們有一些方法可以打斷事件循環並掛鈎它來做自己的事情。

#3


The best way to go is creating a QWidget with what you need, and using it from within a MPxCommand thru the C++ API. That way you also have the chance to inject complete custom editors into Maya via scriptedPanels.

最好的方法是使用您需要的東西創建一個QWidget,並通過C ++ API在MPxCommand中使用它。這樣你也有機會通過scriptedPanels向Maya注入完整的自定義編輯器。

But if you're bound to Python, pyQt is the way to go.

但是如果你被Python綁定了,那么pyQt就是你的選擇。


注意!

本站翻译的文章,版权归属于本站,未经许可禁止转摘,转摘请注明本文地址:https://www.itdaan.com/blog/2008/12/29/72558b36d6abaa54562d3cb4b8eedcd.html



 
粤ICP备14056181号  © 2014-2021 ITdaan.com