Autodesk 3ds Max ships with a pre-built version of PySide 1.2 compatible with Python 2.7.6. This version includes all standard PySide modules.
The following simple example shows how to obtain a handle for the PySide application object and create a widget:
'''
Demonstrates how to create a QWidget with PySide and attach it to the 3dsmax main window.
'''
from PySide import QtGui
import MaxPlus
class _GCProtector(object):
widgets = []
def make_cylinder():
obj = MaxPlus.Factory.CreateGeomObject(MaxPlus.ClassIds.Cylinder)
obj.ParameterBlock.Radius.Value = 10.0
obj.ParameterBlock.Height.Value = 30.0
node = MaxPlus.Factory.CreateNode(obj)
time = MaxPlus.Core.GetCurrentTime()
MaxPlus.ViewportManager.RedrawViews(time)
return
app = QtGui.QApplication.instance()
if not app:
app = QtGui.QApplication([])
def main():
MaxPlus.FileManager.Reset(True)
w = QtGui.QWidget(MaxPlus.GetQMaxWindow())
_GCProtector.widgets.append( w )
w.resize(250, 100)
w.setWindowTitle('PySide Qt Window')
main_layout = QtGui.QVBoxLayout()
label = QtGui.QLabel("Click button to create a cylinder in the scene")
main_layout.addWidget(label)
cylinder_btn = QtGui.QPushButton("Cylinder")
cylinder_btn.clicked.connect(make_cylinder)
main_layout.addWidget(cylinder_btn)
textEdit = QtGui.QLineEdit()
textEdit.setText("Edit box")
main_layout.addWidget(textEdit)
w.setLayout( main_layout )
w.show()
if __name__ == '__main__':
main()
Notes:
Normally one creates a PySide application object in a script using QtGui.QApplication(). However, in 3ds Max, there is already a PySide application running, so you get a handle for that object like this:
QtGui.QApplication.instance()
Nodes created within a script may not appear in Max until the script exits, unless you force a viewport update. You can do so with MaxPlus.ViewportManager.ForceCompleteRedraw() or MaxPlus.ViewportManager.RedrawViews().
MaxPlus provides a facility for loading UI files created by Qt Designer: MaxPlus.LoadUiType(). For example:
import pysideuic
from PySide import QtCore, QtGui
fname = "scripts/python/example.ui"
formt, btype = MaxPlus.LoadUiType(fname)
class TestWidget(btype, formt):
def __init__(self, parent=None):
btype.__init__(self)
formt.__init__(self)
self.setupUi(self)
form = TestWidget()
form.show()