Minh Tuan Nguyen
Minh Tuan Nguyen

Reputation: 137

MAXscript Listener can not run Pyside

Please help me !

I'm creating GUI by Python can run on the 3Ds Max, i heard someone said i have to use Pyside to make it. And everthing be fine until now.

This is my code :

import sys
from PySide import QtGui
from PySide.QtGui import *
from PySide.QtCore import *

class Window(QDialog):
    def __init__(self, parent=None):
        super(Window, self).__init__(parent)

        self.setMinimumHeight(660)
        self.setMinimumWidth(700)
        self.setMaximumHeight(660)
        self.setMaximumWidth(700)

        grid = QtGui.QGridLayout()
        grid.addWidget(self.First(), 0,0,2,0)


        self.setLayout(grid)

        self.setWindowTitle("Library")
        self.resize(700, 660)

    def First(self):
        groupBox = QtGui.QFrame()
        groupBox.setMaximumWidth(230)
        groupBox.setMaximumHeight(700)

        lbRenderer = QtGui.QLabel("Renderer :",self)
        lbFolders = QtGui.QLabel("Folders :",self)

        cbRenderer = QtGui.QComboBox(self)
        cbRenderer.addItem("Vray")
        cbRenderer.addItem("Octane")

        lvFolders = QtGui.QListView(self)
        lvFolders.setMaximumWidth(220)
        lvFolders.setMaximumHeight(500)

        btnAddNewObject = QtGui.QPushButton('Add New Objects',self)
        btnNewSet = QtGui.QPushButton('New Set',self)


        vbox = QtGui.QGridLayout()
        vbox.addWidget(lbRenderer,0,0)
        vbox.addWidget(cbRenderer,0,1,1,3)
        vbox.addWidget(lbFolders,2,0,1,4)
        vbox.addWidget(lvFolders,3,0,1,4)
        vbox.setColumnStretch(1, 1)
        vbox.addWidget(btnAddNewObject,4,0,1,2)
        vbox.addWidget(btnNewSet,4,3)


        groupBox.setLayout(vbox)
        return groupBox

app = QApplication.instance()
if app is None:
    app = QApplication(sys.argv)
    clock = Window()
    clock.show()
app.exec_()

I try another code same like my code , it run fine by "MAXScript Listener". But I dont know why when i try to run this, it dont appear anything(my GUI, or Alert is my code is not good).

This is my command

Upvotes: 0

Views: 909

Answers (2)

IAmNoone
IAmNoone

Reputation: 1011

First of all - you are initializing your script wrong, you call the 'initialize' function which returns #Success (meaning python initialized properly), however you then just send in a string (which is the path to the file) and this does nothing. What you have to use is:

 python.ExecuteFile "C:\\Program Files\\Autodesk\\3ds Max 2015\\scripts\\Python\\yourPythonScript.py"

in maxscript listener\editor.

Autodesk documentation says:

Autodesk 3ds Max ships with a pre-built version of PySide 1.2 compatible with Python 2.7.3. This version includes the following sub-set of modules:

QtCore
QtGui
QtNetwork
QtOpenGL
QtSql
QtSvg
QtTest
QtWebKit
QtXml

They have provided a simple sample script that you can run, save this in a python file, then execute it properly with the command mentioned in the beginning.

The code is here:

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()
    w.resize(250, 100)
    w.setWindowTitle('Window')
    _GCProtector.widgets.append(w)
    w.show()

    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")
    main_layout.addWidget(cylinder_btn)
    w.setLayout(main_layout)

    cylinder_btn.clicked.connect(make_cylinder)

if __name__ == '__main__':
    main()

They also mention this which is important:

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()

Use that as a start script, and port your GUI items into that and it should get you up and running.

Upvotes: 1

Minh Tuan Nguyen
Minh Tuan Nguyen

Reputation: 137

I tried to fix your code but anything happen, i dont know why. First thing , i opened your code and run it in Pycharm but it can not run. But it totally run in Maxscript Listener, could you explain to me ?

Second i tried to fix your code. It's all the same, i can run it on Maxscript, but the content and function inside is disappear.

This is my code

from PySide import QtGui
import MaxPlus

class _GCProtector(object):
    widgets = []


app = QtGui.QApplication.instance()
if not app:
    app = QtGui.QApplication([])

    def main():
        MaxPlus.FileManager.Reset(True)
        w = QtGui.QWidget()
        w.setWindowTitle('Window')
        _GCProtector.widgets.append(w)
        w.show()

        main_layout = QtGui.QGridLayout()
        main_layout.addWidget(First(),0,0)
        main_layout.addWidget(Second(),0,1)
        w.setLayout(main_layout)

    def First():
        groupBox = QtGui.QFrame()
        lbRenderer = QtGui.QLabel("Renderer :",self)
        vbox = QtGui.QGridLayout()
        vbox.addWidget(lbRenderer,0,0)
        groupBox.setLayout(vbox)
        return groupBox

    def Second():
        groupBox = QtGui.QFrame()
        lbRenderer = QtGui.QLabel("Renderer :",self)
        vbox = QtGui.QGridLayout()
        vbox.addWidget(lbRenderer,0,0)
        groupBox.setLayout(vbox)
        return groupBox

if __name__ == '__main__':
    main()

And this is the alert from Maxcript

Upvotes: 0

Related Questions