I temporarily avoided this error by calling the QMessageBox.show() method, which does not halt the execution of the code.
However, rather than finding more workarounds, I would like to find a solution and get to the bottom of this issue.
from PySide2 import QtCore, QtWidgets
from maya.OpenMayaUI import MQtUtil
from pymel import core as pm
from shiboken2 import wrapInstance
# this code is an overly simplified version of the original script
# its only purpose is to recreate the issue described in the post above
# paste it the script editor, *change the ui's file_path variable to an existing .ma file* , and run it
#
# the callback destroys the ui object, before the ui.close() instruction can be executed
# causing a # RuntimeError: Internal C++ object (ImportFileUI) already deleted. # or often even a maya crash
# how can this be prevented?
ui_name = 'ImportFileUI'
def get_maya_window():
pointer = MQtUtil.mainWindow()
return wrapInstance(long(pointer), QtWidgets.QMainWindow)
class ImportFileUI(QtWidgets.QDialog):
def __init__(self, parent):
super(ImportFileUI, self).__init__(parent)
self.setObjectName(ui_name)
self.file_path = r"C:\example_file.ma"
self.btn = QtWidgets.QPushButton("Import File")
self.btn.clicked.connect(self.onBtnClicked)
self.setLayout(QtWidgets.QVBoxLayout())
self.layout().addWidget(self.btn)
def onBtnClicked(self):
pm.importFile(self.file_path, force=True)
QtWidgets.QMessageBox.information(get_maya_window(), "Info", "Scene was imported correctly")
self.close()
def create_ui():
if pm.control(ui_name, exists=True):
pm.deleteUI(ui_name)
ui = ImportFileUI(get_maya_window())
ui.show()
pm.scriptJob(e=["PostSceneRead", create_ui], parent=ui_name)
if __name__ == "__main__":
create_ui()
Thank you for your help!
Enrico
Hi all,I write here because I'm dealing with an issue that makes my maya crash all the times.I have found a workaround (explained later), but I'm still curious to know if there's a better solution.Basically I want to display some messages to the user using a modal dialog (QMessageBox.information()).I have a function (called from a ui) that is used to import a file in the maya scene. This is working fine.I also have a callback attached to that piece of ui, which is meant to update it (by deleting it and recreating it) every time a file is imported.What happens is that when I click on the Import button, the file is imported, the QMessageBox is shown, the code execution is paused (because of the modal dialog), but the callback is fired anyways.Since the callback deletes (and recreates) the dialog, when the code finally reaches the ui "self.close()" instruction, the ui object was already destroyed - thus resulting in a # RuntimeError: Internal C++ object (ImportFileUI) already deleted. # or more often than not a sudden maya crash.
I temporarily avoided this error by calling the QMessageBox.show() method, which does not halt the execution of the code.
However, rather than finding more workarounds, I would like to find a solution and get to the bottom of this issue.
Does anyone have an idea of how to make the callback "wait"? Are there better practices to deal with a similar situation?I tried to delay the execution of the callback using "evalDeferred()" and even "processIdleEvents()", but none of them really made any difference.
def onBtnClicked(self):
pm.importFile(self.file_path, force=True)
self.deleteLater()
QtWidgets.QMessageBox.information(get_maya_window(), "Info", "Scene was imported correctly")
--
You received this message because you are subscribed to the Google Groups "Python Programming for Autodesk Maya" group.
To unsubscribe from this group and stop receiving emails from it, send an email to python_inside_m...@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/python_inside_maya/f4fcd5e0-00fa-4bb1-ad0d-feecc8504f25o%40googlegroups.com.
def create_ui():
def callback():
# checks whether a modal dialog exists
modal_dialog = QtWidgets.QApplication.activeModalWidget()
if modal_dialog:
# connects the ui's 'finished' signal to the (deferred) callback
modal_dialog.finished.connect(lambda: maya.utils.executeDeferred(callback))
return
# call the ui creation function (only if a modal dialog doesn't exist)
maya.utils.executeDeferred(create_ui)
if pm.control(ui_name, exists=True):
pm.deleteUI(ui_name)
ui = ImportFileUI(get_maya_window())
ui.show()
pm.scriptJob(e=["PostSceneRead", callback], parent=ui_name)
I've tested also adding a bunch of instructions between the QMessageBox and the self.close(), and still the callback waits until all the commands are executed!
def onBtnClicked(self):
pm.importFile(self.file_path, force=True)
QtWidgets.QMessageBox.information(get_maya_window(), "Info", "Scene was imported correctly")
for i in range(1000):
print(self.objectName, i)
self.close()
To unsubscribe from this group and stop receiving emails from it, send an email to python_inside_maya+unsub...@googlegroups.com.
To unsubscribe from this group and stop receiving emails from it, send an email to python_inside_m...@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/python_inside_maya/f4fcd5e0-00fa-4bb1-ad0d-feecc8504f25o%40googlegroups.com.
--
You received this message because you are subscribed to the Google Groups "Python Programming for Autodesk Maya" group.
To unsubscribe from this group and stop receiving emails from it, send an email to python_inside_m...@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/python_inside_maya/a8dc8dc2-82fd-4ac4-84bc-a6465d128124o%40googlegroups.com.