【问题标题】:How to run OpenMaya.MCommandMessage without crashing Maya如何在不使 Maya 崩溃的情况下运行 OpenMaya.MCommandMessage
【发布时间】:2020-04-04 15:58:04
【问题描述】:

我正在尝试获取 Maya 的日志(它在脚本编辑器的输出窗口中打印的内容)并将其添加到我的自定义 PySide Qwidget。 为什么这会使 Maya 崩溃

QtWidgets, QtCore, QtGui
imoprt QtDesiner_UI
import maya.OpenMayaUI as OmUi
from shiboken2 import wrapInstance
import maya.OpenMaya as Om

def get_maya_window():
    # Get Maya window
    maya_main_window_ptr = OMUI.MQtUtil.mainWindow()

    maya_main_window = wrapInstance(long(maya_main_window_ptr), 
    QtWidgets.QMainWindow)

    return maya_main_window

class UiClass(QtWidgets.QMainWindow, QtDesiner_UI.MainWindow):

    def __init__(self):
        super(UiClass, self).__init__(get_maya_window())

        OM.MCommandMessage.addCommandOutputFilterCallback(self.callback)
        # some PySide Widgets here
        self.console_widget = QtWidgets.QTextEdit()
        self.main_form_layout.addRow(self.console_widget)

    def callback(self, msg, mg, *args):
       self.console_widget.append(msg)

    def logic_stuff(self):
        #maya commands here

import UI_Window
w = UI_Window.UiClass()
w.show()

这不是

def callback(msg, mg ,*args):
    console_widget.append(var)

OM.MCommandMessage.addCommandOutputFilterCallback(callback)

这是部分工作的工作代码。它应该将日志信息附加到“QtextEdit()”中,但在第一次操作之后 Maya 崩溃(例如创建球体)。

import maya.OpenMayaUI as OmUi
from shiboken2 import wrapInstance
from PySide2 import QtWidgets, QtCore, QtGui
import maya.OpenMaya as Om

def get_maya_window():
    # Get Maya window
    maya_main_window_ptr = OmUi.MQtUtil.mainWindow()
    maya_main_window = wrapInstance(long(maya_main_window_ptr), QtWidgets.QMainWindow)
    return maya_main_window

class MainWidget(QtWidgets.QMainWindow):
    def __init__(self):
        super(MainWidget, self).__init__(get_maya_window())

        self.cent_ly = MW()
        self.text_edit = QtWidgets.QTextEdit()
        self.cent_ly.vlayout.addWidget(self.text_edit )
        self.setCentralWidget(self.cent_ly )

        self.callback_id = Om.MCommandMessage.addCommandOutputFilterCallback(self.callback)

    def closeEvent(self, event):
        Om.MMessage.removeCallback(self.callback_id)

    def callback(self, message):
        self.text_edit.append(message.strip())

class MW(QtWidgets.QWidget):
    def __init__(self):
        super(MW , self).__init__()
        self.vlayout = QtWidgets.QVBoxLayout()        
        self.setLayout(self.vlayout)

w = MainWidget()
w.show()

而且这个不会让 Maya 崩溃

import maya.OpenMayaUI as OmUi
from shiboken2 import wrapInstance
from PySide2 import QtWidgets, QtCore, QtGui
import maya.OpenMaya as Om

def get_maya_window():
    # Get Maya window
    maya_main_window_ptr = OmUi.MQtUtil.mainWindow()
    maya_main_window = wrapInstance(long(maya_main_window_ptr), QtWidgets.QMainWindow)
    return maya_main_window

class MainWidget(QtWidgets.QMainWindow):
    def __init__(self):
        super(MainWidget, self).__init__(get_maya_window())

        self.cent_ly = MW()
        self.text_edit = QtWidgets.QTextEdit()
        self.cent_ly.vlayout.addWidget(self.text_edit)
        self.setCentralWidget(self.cent_ly )

class MW(QtWidgets.QWidget):
    def __init__(self):
        super(MW , self).__init__()
        self.vlayout = QtWidgets.QVBoxLayout()        
        self.setLayout(self.vlayout)

w = MainWidget()
w.show()

def callback(message,  *args):
    w.text_edit.append(message.strip())

callback_id = Om.MCommandMessage.addCommandOutputFilterCallback(callback)

# Om.MMessage.removeCallback(callback_id)

【问题讨论】:

    标签: python maya maya-api


    【解决方案1】:

    您需要在关闭窗口时移除回调。我正在测试你的代码,它第一次工作,但后来冻结了 Maya。

    class UiClass(QtWidgets.QMainWindow):
        def __init__(self):
            super(UiClass, self).__init__(get_maya_window())
            self.callback_id = Om.MCommandMessage.addCommandOutputFilterCallback(self.callback)
    
        def closeEvent(self, event):
            Om.MMessage.removeCallback(self.callback_id)
    

    就像@ababak 所说,崩溃是因为对象被破坏而发生的,当你关闭窗口时就会发生这种情况。因此,在此之前,您需要移除回调。

    【讨论】:

    • 感谢它部分解决了问题,现在它在您执行一些生成消息的操作后使 Maya 崩溃。例如。创建定位器或在视口中选择一些节点。
    • @iRex 这可能是之前的窗口已经被销毁但仍然订阅了回调。
    • @ababak 我只调用一次怎么可能?
    【解决方案2】:

    您还没有展示第一个示例的完整代码。

    这些崩溃发生在回调被触发但原始对象已被销毁时。

    我假设您创建了 UiClass 对象,但后来它被垃圾回收了。 当您在全局范围内定义回调函数时,第二个示例不会崩溃,并且在您退出 Maya 之前它一直有效。

    【讨论】:

    • 对不起,我不能发布整个代码,但我添加了一些行来显示代码的一般用途。我有需要更新的 UI。如何避免垃圾回收?
    • 抱歉,即使您在问题中添加了一些代码,我仍然看不到您创建 UiClass 对象的位置。
    • 很抱歉被误解了。我已经添加了线条。首先我导入模块。然后我创建对象并使用show() 调用它
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-08-11
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多