English 中文(简体)
使用外部GUI库在Autodesk Maya中创建用户界面
原标题:
  • 时间:2008-12-29 08:41:12
  •  标签:

我在Autodesk Maya中开发工具。我构建的许多工具都有简单的窗口化GUI供动画师和建模师使用。这些GUI通常包含您通常会在任何基本窗口中看到的内容,如标签、列表、菜单、按钮、文本字段等。然而,使用现有工具构建UI的复杂度有限,特别是在可用widget类型方面。

我有兴趣使用一些更先进的wxPython小部件,如ListView(网格)、树等。这将涉及使用完整的wxFrame(窗口)来显示整个UI,这基本上意味着窗口不再与Maya绑定。这不是一个致命问题,但这意味着当Maya最小化时,窗口将不会跟随。

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

wxPython有相同的“主循环”方法论。我想知道是否有任何方法可以绕过它,使它可以在Maya中运行?

最佳回答

我不确定这是否相关,但一些谷歌搜索显示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()

应对当前事项清单。

祝你好运!

问题回答

我不知道是否有一个绕过主循环的方法来处理图形用户界面,因为它需要处理所有事件链和重绘队列。

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.

你可以看看IPython,这是一个交互式的Python shell,其开发团队已经花费了一些精力将它与wxPython集成。他们有一些打断事件循环并钩入其中以执行自己的任务的方式。

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

但如果你与Python绑定,pyQt是前进的方式。





相关问题
热门标签