使用外部GUI库在Autodesk Maya中创建用户界面

8
我在 Autodesk Maya 中开发工具。我构建的许多工具都有简单的窗口 GUI,供动画师和建模师使用。这些 GUI 通常包含任何基本窗口中所期望看到的内容;标签、列表、菜单、按钮、文本字段等。然而,使用可用工具构建 UI 的复杂性存在限制,特别是在可用小部件类型方面。
我有兴趣使用一些更高级的 wxPython 小部件,例如 ListView(网格)、Tree 等。这将涉及使用完整的 wxFrame(窗口)来显示整个 UI,这实际上意味着该窗口将不再与 Maya 绑定。这并不是致命问题,但这意味着当 Maya 最小化时,窗口不会跟随最小化。
我之前尝试过使用 tkinter 进行测试,但发现它需要在自己的线程中运行 MainLoop。这是合理的,但在我的情况下,它与 Maya 自己的线程冲突,从本质上让 Maya 挂起,直到关闭窗口为止。这是由于 Maya 在单个线程中运行所有脚本,无论是 MEL 还是 Python,主 Maya GUI 共享该线程。这是为了防止一个脚本删除对象,而另一个脚本正在尝试在同一对象上执行操作。
wxPython 也采用了这种“mainloop”方法。我想知道是否有任何方法可以避免这种情况,以便它可以在 Maya 中运行?
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。您需要设置一个事件循环并在上面的(pumpQt)函数内检查“Pending”事件,而不是使用processEvents()。(wxPython源代码有一个Python实现的MainLoop。)可能应该通过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()

处理当前的事件列表。
祝你好运!

既然你提到了,我突然想起来听说 Maya 可能会添加本地 QT 支持。所以这可能有很多价值。 - Soviut

0

最佳的方法是创建一个包含所需内容的QWidget,并通过C ++ API从MPxCommand中使用它。这样,您还可以通过scriptedPanels将完整的自定义编辑器注入Maya。

但如果您必须使用Python,则应使用pyQt。


0

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

但是有几种进程间通信的方式,例如管道或信号量。也许将Maya扩展分成实际插件(与Maya紧密集成)和GUI的独立应用程序是一个选择。这两个应用程序可以使用这些方式来在插件和GUI之间通信和交换模型信息。但是,我不确定是否真的推荐这种方法,因为它会使应用程序变得非常复杂。

您可以查看IPython,一个交互式Python shell,其开发团队已经花费了一些精力将其与wxPython集成。他们有一些中断事件循环并连接到其中以执行自己任务的方法。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接