7

我在 Autodesk Maya 中开发工具。我构建的许多工具都有简单的窗口 GUI 供动画师和建模师使用。这些 GUI 通常包含您通常希望在任何基本窗口中看到的内容;标签、列表、菜单、按钮、文本字段等。但是,您可以使用可用工具构建的 UI 的复杂性受到限制,特别是可用小部件的类型。

我有兴趣使用一些更高级的 wxPython 小部件,例如 ListView(网格)、Tree 等。这将涉及使用完整的 wxFrame(窗口)来显示整个 UI,这实际上意味着该窗口将不再与玛雅联系在一起。不是破坏交易,但这意味着当 Maya 最小化时,窗口不会效仿。

我以前用 tkinter 作为测试尝试过这样的事情,但发现它需要一个 MainLoop 才能在自己的线程中运行。这是合乎逻辑的,但在我的情况下,它与 Maya 自己的线程冲突,基本上使 Maya 挂起,直到窗口关闭。这是因为 Maya 在主 Maya GUI 共享的单个线程中运行所有脚本,无论是 MEL 还是 Python。这是为了防止一个脚本在另一个脚本尝试对同一对象执行操作时删除一个对象。

wxPython 有同样的“mainloop”方法。我想知道是否有任何方法可以让它在 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

我不知道是否有办法绕过 gui 的主循环,因为需要它来处理所有事件链和重绘队列。

但是有几种进程间通信方式,如管道或信号量。也许将您的 Maya 扩展拆分为实际插件、紧密集成到 Maya 以及​​用于 gui 的单独应用程序是一种选择。这两者可以使用这种方式在插件和gui之间进行通信和交换模型信息。但是,我不确定我是否真的可以推荐这种方法,因为它使应用程序非常复杂。

你可以看看 IPython,一个交互式 Python shell,它的开发团队已经努力将它与 wxPython 集成。他们有一些方法可以中断事件循环并连接到它来做自己的事情。

于 2008-12-29T19:41:38.260 回答
0

最好的方法是用你需要的东西创建一个 QWidget,并通过 C++ API 在 MPxCommand 中使用它。这样,您还有机会通过 scriptedPanel 将完整的自定义编辑器注入 Maya。

但是,如果您必须使用 Python,那么 pyQt 就是您要走的路。

于 2015-05-14T21:18:00.333 回答