Maya 2017 and PySide 2

2 minute read

We’re just starting to make the transition over to Maya 2017 at work, running through our existing toolset and making any changes as required. One thing that stands out is that PySide (Maya’s Python GUI framework) has been replaced with PySide2! It’s great to see Autodesk updating Maya’s UI toolkit from Qt4 to Qt5, but as this new version breaks backward compatibility for the Python bindings it does mean all of our UI’s will need updating.

Thankfully this is not a huge task, although it’s not as simple as replacing import PySide with import PySide2

The biggest breaking change from PySide (Qt4 bindings) to PySide2 (Qt5) is the creation of the QtWidgets module. All widgets that used to be under QtGui have been moved into this new module, I would guess this separation is to stop the QtGui namespace from becoming bloated in future. There are other major changes in Qt5 which are worth noting, but it’s the changes to PySide that we’re interested in for creating Maya UIs.

Backwards compatibility

Ideally we want to update our tooset to work with PySide2 but also not break compatibility with older Maya versions (2012-2016). This is possible with some simple aliases when importing the Pyside modules.

eg

try:
    from PySide2 import QtCore, QtGui, QtWidgets
    from shiboken2 import wrapInstance
except ImportError:
    from PySide import QtCore, QtGui
    from PySide import QtGui as QtWidgets
    from shiboken import wrapInstance

This way we always get the three core modules QtCore, QtGui and QtWidgets regardless of which version of PySide Maya is using. The only difference being that in the case of PySide we are actually importing QtGui twice … once as itself and once again as QtWidgets. With this taken care of the only remaining work is to replace any calls to QtGui that create widgets to instead call QtWidgets.

eg

class My_ui(QtGui.QDialog):
    def __init__(self, parent=None):
        super(My_ui, self).__init__(parent)
        self.menubar = QtGui.QMenuBar()
        self.main_layout = QtGui.QVBoxLayout()

would need to be rewritten as …

class My_ui(QtWidgets.QDialog):
    def __init__(self, parent=None):
        super(My_ui, self).__init__(parent)
        self.menubar = QtWidgets.QMenuBar()
        self.main_layout = QtWidgets.QVBoxLayout()

Be careful though, not everything you’ll have used from QtGui has moved to QtWidgets! Check the PySide/Qt documentation to be sure.

Comments