Issue parenting loaded Qt .ui file under Maya 2023 application window (Python / Qt)

Issue parenting loaded Qt .ui file under Maya 2023 application window (Python / Qt)

sms-js
Explorer Explorer
1,633 Views
3 Replies
Message 1 of 4

Issue parenting loaded Qt .ui file under Maya 2023 application window (Python / Qt)

sms-js
Explorer
Explorer

Hello!  I've got a longstanding unsolved mystery that I'm finally attempting to solve definitively.

The summary:  I'm able to successfully load standalone Qt files just file, provided they're not parented under the application window, the downside being such UI elements are not managed by Maya's application state (a usability problem)

However if I attempt to group them under the Maya application as the parent control, I get an apparent memory reference error, when attempting to call .show() on the element:

 

# # RuntimeError: Internal C++ object (PySide2.QtWidgets.QWidget) already deleted.

 

 

Here is the code:

 

from maya import OpenMayaUI as omui
from shiboken2 import wrapInstance 

from PySide2.QtCore import *
from PySide2.QtWidgets import *
from PySide2.QtUiTools import QUiLoader 

UI_FILE = 'D:/path/to/my/test_file.ui'

def _main_win():
    main_window_ptr = omui.MQtUtil.mainWindow()
    return wrapInstance(int(main_window_ptr), QWidget)    

ui_file = QFile(UI_FILE)
ui_file.open(QFile.ReadOnly)
loader = QUiLoader()
ui = loader.load(ui_file)
ui.setParent(_main_win())
ui_file.close()
ui.show()

 


If line 18 is commented out, the script manages to work, but as mentioned despite appearing the subsequent UI widget is "unmanaged" and is not appropriately updated when the Maya application state changes.

(Incidentally the contents of the .ui file are seemingly irrelevent.  In my case It's just a simple QWidget containing a VBoxLayout and a button -- that's it.  I'm using Qt Designer 5.15 to save the standalone xml .UI file)

Any help is appreciated, and thanks in advance -


(* Update: .ui file contents (xml) included below, for reference)

 
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
 <class>Form</class>
 <widget class="QWidget" name="Form">
  <property name="geometry">
   <rect>
    <x>0</x>
    <y>0</y>
    <width>303</width>
    <height>154</height>
   </rect>
  </property>
  <property name="windowTitle">
   <string>Qt Creator Form Demo</string>
  </property>
  <layout class="QVBoxLayout" name="verticalLayout_2">
   <item>
    <layout class="QVBoxLayout" name="verticalLayout">
     <property name="sizeConstraint">
      <enum>QLayout::SetDefaultConstraint</enum>
     </property>
     <item>
      <layout class="QFormLayout" name="formLayout">
       <item row="0" column="0">
        <widget class="QLabel" name="label">
         <property name="text">
          <string>Subdivisions XY</string>
         </property>
        </widget>
       </item>
       <item row="1" column="0">
        <widget class="QLabel" name="label_2">
         <property name="text">
          <string>Scale XY</string>
         </property>
        </widget>
       </item>
       <item row="1" column="1">
        <layout class="QHBoxLayout" name="horizontalLayout_2">
         <item>
          <widget class="QDoubleSpinBox" name="scale_x"/>
         </item>
         <item>
          <widget class="QDoubleSpinBox" name="scale_y"/>
         </item>
        </layout>
       </item>
       <item row="0" column="1">
        <layout class="QHBoxLayout" name="horizontalLayout">
         <item>
          <widget class="QSpinBox" name="sub_x"/>
         </item>
         <item>
          <widget class="QSpinBox" name="sub_y"/>
         </item>
        </layout>
       </item>
      </layout>
     </item>
     <item>
      <widget class="QPushButton" name="button_create">
       <property name="text">
        <string>Create</string>
       </property>
      </widget>
     </item>
    </layout>
   </item>
  </layout>
 </widget>
 <resources/>
 <connections/>
</ui>
0 Likes
1,634 Views
3 Replies
Replies (3)
Message 2 of 4

sms-js
Explorer
Explorer

Bumping this.  Note that I've included details of the .ui file contents above...   I feel those details are unrelated to the core issue here, but in case anyone would like to repro the behavior I'm seeing, they can now do so.

I've played around locally but the core issue remains:  parenting a manually allocated Python widget (and children) under the application works as expected, with the subsequent UI managed by the application.

However loading a widget hierarchy from the .ui file and parenting that under the Maya application results in the exception mentioned.  And the workaround of not parenting the loaded root widget has the knock-on effect of not being managed by the application instance.

Any insight here is appreciated (and thanks)

Message 3 of 4

sms-js
Explorer
Explorer

Bumping this again... in principle there should be no issue loading a Qt .UI file and parenting it to the Maya main window.

Yet in practice, I've been unable to find a pattern that actually does so, without throwing an exception re: the underlaying C++ going out of scope (despite keeping references to the loaded object)

Thanks again, and any assistance is appreciated

0 Likes
Message 4 of 4

FirespriteNate
Advocate
Advocate

I don't know what's wrong with the way you're doing it, but my advice is to just not do it like that.

This is how I would do it, keeping it as close to your original code as possible:

from maya import OpenMayaUI as omui
from shiboken2 import wrapInstance

from PySide2.QtCore import *
from PySide2.QtWidgets import *
from PySide2.QtUiTools import QUiLoader 

UI_FILE = 'D:/path/to/my/test_file.ui'

def _main_win():
    main_window_ptr = omui.MQtUtil.mainWindow()
    return wrapInstance(int(main_window_ptr), QWidget)    

class MayaWindow(QWidget):
    def __init__(self, parent=None):
        super(MayaWindow, self).__init__(parent=parent)
        self.setWindowFlags(Qt.Window)
        self.widget = QUiLoader().load(UI_FILE)
        self.widget.setParent(self)

mayaMainWindow = _main_win()
ui = MayaWindow(parent=mayaMainWindow)
ui.show()