我在Autodesk Maya中开发工具。我构建的许多工具都有简单的窗口GUI,供动画师和建模人员使用。这些GUI通常包含您通常希望在任何基本窗口中看到的内容;标签,列表,菜单,按钮,文本字段等。但是,使用可用工具构建的UI的复杂性存在限制,特别是在可用小部件的类型中。
我有兴趣使用一些更高级的wxPython小部件,例如ListView(网格),树等。这将涉及使用完整的wxFrame(窗口)来显示整个UI,这实际上意味着该窗口将不再与玛雅联系在一起。不是交易破坏者,但这意味着当Maya被最小化时,窗口将不会效仿。
我之前尝试使用tkinter作为测试,但发现它需要MainLoop才能在自己的线程中运行。这是合乎逻辑的,但在我的情况下,它与Maya自己的线程冲突,基本上使Maya挂起,直到窗口关闭。这是因为Maya在主Maya GUI共享的单个线程中运行所有脚本,无论是MEL还是Python。这是为了防止一个脚本在另一个脚本尝试对同一个对象进行操作时删除一个对象。
wxPython有同样的“mainloop”方法论。我想知道它是否有任何解决方法,以便它可以在Maya中工作?
答案 0 :(得分:2)
我不确定这是否密切相关,但有些谷歌搜索结果表明PyQt在Maya中很受欢迎。您可以尝试通过Maya创建新的threadloop并在其中执行的技术here或here(用源代码解释here)。似乎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上创建non-blocking GUI。您需要设置一个事件循环并检查上面(希望重命名的?)pumpQt函数中的“Pending”事件,而不是processEvents()。 (wxPython源代码有一个Python implementation的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 docs indicate SafeYield()是首选。再次,这似乎可能是第一步,但我不确定它会起作用,而不仅仅是崩溃可怕。 (关于你想要对wxPython mailing list做什么的讨论,但它来自wx之前的几个小版本。)在各种论坛中也有一些迹象表明这种技术会导致键盘输入问题。您也可以尝试:
def processor():
while app.Pending(): app.Dispatch()
处理当前的事件列表。
祝你好运!答案 1 :(得分:0)
我不知道gui是否有绕过mainloop的方法,因为它需要处理所有事件链和重绘队列。
但是有几种进程间通信方式,比如管道或信号量。也许它是一个选项,可以将Maya扩展分成实际的插件,紧密分为maya,以及单独的gui应用程序。这两个可以使用这种方法在插件和gui之间进行通信和交换模型信息。 但是,我不确定我是否真的可以推荐这种方法,因为它使应用程序非常复杂。
你可以看看IPython,一个交互式的Python shell,它的开发团队已经付出了一些努力将它与wxPython集成。他们有一些方法可以打断事件循环并挂钩它来做自己的事情。
答案 2 :(得分:0)
最好的方法是使用您需要的东西创建一个QWidget,并通过C ++ API在MPxCommand中使用它。这样你也有机会通过scriptedPanels将完整的自定义编辑器注入Maya。
但如果你被绑定到Python,那么pyQt就是你的选择。