Building QT Designer UI to be used for Maya and Max

I am working in Maya 2018, 2019 and potentially Maya 2020 as well as Max 2019 and 2020. I need to build an interface in QTDesigner and use it for both Maya and Max.
I’m starting with Maya and basically built a fully functioning maya version written in Python with Pyside2 but now that I have proven the functionality and pipeline, I am trying to move all of the UI out to QTDesigner, .ui, file. I get a window for a nano second but nothing shows up and it closes.

import shiboken2

Maya specific libs

from PySide2.QtCore import *
from PySide2.QtUiTools import *
from PySide2.QtWidgets import *
import maya.OpenMayaUI as omui

def get_main_window():
main_window_ptr = omui.MQtUtil.mainWindow()
return shiboken2.wrapInstance(long(main_window_ptr), QWidget)

main_window = get_main_window()

class Main(QObject):
def init(self):
super(Main, self).init(main_window)
ui_file = QFile(“T:/utils/VAT/VATUI.ui”)
loader = QUiLoader()
window = loader.load(ui_file)

    btn = window.findChild(QPushButton, 'ExportAs')

def closeEvent(self, event):
    on close, this closes the ui
    super(Main, self).closeEvent(event)


Am I missing something?
Is this a good way to create a tool for both programs that has to look and act the same?


Morris Olmsted
Sr. Technical Artist|Army Game Studio

Yes, this is a good way to create one UI for use in multiple DCCs. However, not every DCC simply works correctly by using the MainWindow of the DCC as parent. It might be sufficient for your targeted DCCs though - not sure if Max 2019 has a full Qt based UI though, so that might not work.

The modern libraries of those DCCs provide functions to correctly attach a widget as a child to the MainWindow like AttachQWidgetToMax for 3dsMax for example. So you might want to write this more dynamically, having the window call a DCC-specific function when it is created instead of just using the parent parameter for the __init__ call.

I am not sure if this is still the case and if that is the reason why your window dies immediately. In the older days (3dsMax 2015 etc.), due to no real python-based attachment between the Qt windows, the created window was garbage-collected. So what we generally do is to keep a module-level (or global) variable that references the created window instance to make sure the python gc doesn’t delete it my_window_instance = my_tool.MainWindow().

To be fair, the above example was just the Maya python call to the ui. Knowing that the Max one would have a different call and setup for how to run commands. Only the .UI file would be exactly the same for both.

Max has been using Qt since at least 2014, maybe longer.