need help with userSetup.py and calling a script that is mainly a class.

293 views
Skip to first unread message

md

unread,
Feb 15, 2016, 3:09:21 PM2/15/16
to Python Programming for Autodesk Maya
Hey Guys,

I am building my own Maya menu through userSetup.py ... 

I have written another python script which is basically just a pySide class. I want to call this script from the menu created in userSetup.py.

There is no main function .. just the class that gets instantiated at the bottom of the script with the following code. The script runs fine when run from the script editor.

Any insight would be awesome.

if __name__ == "__main__":
    
    try:
        cam_ui.deleteLater()
    except:
        pass
    
    cam_ui = smRealCameras()
    
    try:
        cam_ui.create()
        cam_ui.show()
    except:
        cam_ui.deleteLater()
        traceback.print_exc()        

I get this error in the command window when Maya launches ...

Failed to execute userSetup.py
Traceback (most recent call last):
  File "K:\ifs\resources\3D_resources\workgroups\maya_workgroup\net_modules\sm_module\scripts\userSetup.py", line 11, in <module>
    from create_cam_class import smRealCameras
  File "K:\ifs\resources\3D_resources\workgroups\maya_workgroup\net_modules\sm_module\scripts\create_cam_class.py", line 36, in <module>
    class smRealCameras (QtGui.QDialog) :
  File "K:\ifs\resources\3D_resources\workgroups\maya_workgroup\net_modules\sm_module\scripts\create_cam_class.py", line 37, in smRealCameras
    def __init__(self, parent=maya_main_window()):
  File "K:\ifs\resources\3D_resources\workgroups\maya_workgroup\net_modules\sm_module\scripts\create_cam_class.py", line 33, in maya_main_window
    return wrapInstance(long(main_window_ptr), QtGui.QWidget)
TypeError: long() argument must be a string or a number, not 'NoneType'

... here is my userSetup.py that builds the menu

import traceback

import maya.cmds as cmds
import maya.mel as mel
import maya.utils as utils
 
import sm_CreateProjectPlugin
from sm_CreateProjectPlugin_Maya_v0003 import *

import create_cam_class
from create_cam_class import smRealCameras

cmds.evalDeferred("build_menu()")

def build_menu():
if cmds.menu('sm_menu', exists=1):
cmds.deleteUI('sm_menu')
sm_menu = cmds.menu('sm_menu', parent='MayaWindow', tearOff=True, allowOptionBoxes=True, label='[===my menu===]')
cmds.menuItem( divider=True)
cmds.menuItem(parent=sm_menu,  subMenu = True, label="Pipeline               ")
cmds.menuItem(l="create project", c = createProjectWindow)
cmds.menuItem(l ="real cams" c = smRealCameras)
cmds.menuItem(parent=sm_menu, divider=True)
cmds.menuItem(parent=sm_menu, subMenu = True, label="Rendering", enable=True)
cmds.menuItem(label="setup passes")
cmds.menuItem(label="render manager") 
cmds.menuItem(parent=sm_menu, label="Modeling",enable=False)
cmds.menuItem(parent=sm_menu, label="Lighting",enable=False)
cmds.menuItem(parent=sm_menu, divider=True)

Mike

Robert White

unread,
Feb 15, 2016, 3:30:49 PM2/15/16
to Python Programming for Autodesk Maya
Looks like your error is in your create_cam_class.py file, not in your userSetup.py, probably something in that file is trying to interact with the GUI outside of your evalDeferred call. 
You could probably try testing it by moving the import create_cam_class and from_cam_class import smRealCameras into your build_menu function, that way the import will be deferred along with the rest of the menu.
Message has been deleted

md

unread,
Feb 15, 2016, 3:37:10 PM2/15/16
to Python Programming for Autodesk Maya
thanks ... ill give that a try .. hey is there a way for me to resource usersetup.py so I don have to quit and relaunch Maya to see my changes to userSetup.py ?
Message has been deleted

md

unread,
Feb 15, 2016, 3:52:10 PM2/15/16
to Python Programming for Autodesk Maya
After moving the imports into the build section of my userSetup.py as you suggested I was able to get the menu to appear in Maya ... but when I attempted to run the script from the menu I got the following error in the log window ...

// Error: 'PySide.QtGui.QDialog' called with wrong argument types:

# PySide.QtGui.QDialog(bool)

# Supported signatures:

# PySide.QtGui.QDialog(PySide.QtGui.QWidget = None, PySide.QtCore.Qt.WindowFlags = 0)

# Traceback (most recent call last):

# File "K:\ifs\resources\3D_resources\workgroups\maya_workgroup\net_modules\sm_module\scripts\create_cam_class.py", line 38, in __init__

# super(smRealCameras, self).__init__(parent)

# TypeError: 'PySide.QtGui.QDialog' called with wrong argument types:

# PySide.QtGui.QDialog(bool)

# Supported signatures:

# PySide.QtGui.QDialog(PySide.QtGui.QWidget = None, PySide.QtCore.Qt.WindowFlags = 0) //


The area of the script where I am calling QDialog is below ...

def maya_main_window():
    main_window_ptr = omui.MQtUtil.mainWindow()
    return wrapInstance(long(main_window_ptr), QtGui.QWidget)

 
class smRealCameras (QtGui.QDialog) :
    def __init__(self, parent=maya_main_window()):
        super(smRealCameras, self).__init__(parent)
    
    def create(self):

... ... ... .... etc etc
        

David Moulder

unread,
Feb 15, 2016, 3:57:59 PM2/15/16
to python_inside_maya
The clue is in the exception stack.  Your script, line 38 is the where things are starting to go bad.  You are creating and instance of your dialog and passing in a boolean instance.  True or False.  It's also telling you how the code is expected to be called.

You should be passing either None or a QWidget instance.  Which should probably be the Maya main window.  There are lots of examples on how to get the main window QWidget instance. 

Example class

class MyWin(QDialog):
    def __init__(self, parent=None):
        super(MyDialog, self).__init__(parent)
        self.setMainLayout(QHBoxLayout())
        self.layout().addWidget(QPushButton("HI"))

win = MyWin(None)
win.show()




On Mon, Feb 15, 2016 at 8:45 PM, md <acco...@mdonovan.com> wrote:
I get this error in my script editor when I try to execute the script from the menu after moving the lines you mentioned....

// Error: 'PySide.QtGui.QDialog' called with wrong argument types:

# PySide.QtGui.QDialog(bool)

# Supported signatures:

# PySide.QtGui.QDialog(PySide.QtGui.QWidget = None, PySide.QtCore.Qt.WindowFlags = 0)

# Traceback (most recent call last):

# File "K:\ifs\resources\3D_resources\workgroups\maya_workgroup\net_modules\sm_module\scripts\create_cam_class.py", line 38, in __init__

# super(smRealCameras, self).__init__(parent)

# TypeError: 'PySide.QtGui.QDialog' called with wrong argument types:

# PySide.QtGui.QDialog(bool)

# Supported signatures:

# PySide.QtGui.QDialog(PySide.QtGui.QWidget = None, PySide.QtCore.Qt.WindowFlags = 0) //



the line in my script which refer to QDialog are :

--
You received this message because you are subscribed to the Google Groups "Python Programming for Autodesk Maya" group.
To unsubscribe from this group and stop receiving emails from it, send an email to python_inside_m...@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/python_inside_maya/e2a38a35-c4e3-4bfa-989a-d63da6f0d2a6%40googlegroups.com.

For more options, visit https://groups.google.com/d/optout.



md

unread,
Feb 15, 2016, 4:09:02 PM2/15/16
to Python Programming for Autodesk Maya
I am passing the result of maya_main_window which is a result of wrapInstance ... I thought I needed to do this in order to get Maya to be the parent window .. otherwise my dialogs could fall behind Maya ... no ?


David Moulder

unread,
Feb 15, 2016, 4:25:33 PM2/15/16
to python_inside_maya
Your correct,  Who is calling your class?  The menu callback function?
It's been a while but from what I remember some callbacks in Maya send extra arguments into the function.  So parent=maya_main_window() may actually be something else.

Also I'm not keen on the method of setting the result of a function in the class parameters.

Better todo:  

class MyClass(object):
    def __init__(something=None):
        """
        param something : None or QWidget, if None Maya Main window is used instead
        """
        if something is None:
             something = somethingElse()



On Mon, Feb 15, 2016 at 9:09 PM, md <acco...@mdonovan.com> wrote:
I am passing the result of maya_main_window which is a result of wrapInstance ... I thought I needed to do this in order to get Maya to be the parent window .. otherwise my dialogs could fall behind Maya ... no ?


--
You received this message because you are subscribed to the Google Groups "Python Programming for Autodesk Maya" group.
To unsubscribe from this group and stop receiving emails from it, send an email to python_inside_m...@googlegroups.com.

For more options, visit https://groups.google.com/d/optout.

md

unread,
Feb 15, 2016, 4:30:29 PM2/15/16
to Python Programming for Autodesk Maya
Yes .. the menu call back is instantiating the the class. When I run the script from the script editor or call it form the command line it runs fine.

Justin Israel

unread,
Feb 15, 2016, 4:53:10 PM2/15/16
to Python Programming for Autodesk Maya
Where is the calling line where the dialog instance actually gets constructed? Not the constructor itself.

Also, I think doing this (and I see it alot) might be a bad idea:

def __init__(self, parent=maya_main_window()):

Reason being that the default argument value is going to be evaluated once when the class is first read. This means if you were to import your UI code early, before there is a Maya window, your default value will end up being None. I recommend evaluating it within the constructor:

def __init__(self, parent=None):
    if parent is None:
        parent = maya_main_window()
    ...


Justin


On Tue, Feb 16, 2016 at 10:30 AM md <acco...@mdonovan.com> wrote:
Yes .. the menu call back is instantiating the the class. When I run the script from the script editor or call it form the command line it runs fine.

--
You received this message because you are subscribed to the Google Groups "Python Programming for Autodesk Maya" group.
To unsubscribe from this group and stop receiving emails from it, send an email to python_inside_m...@googlegroups.com.

md

unread,
Feb 15, 2016, 6:00:10 PM2/15/16
to Python Programming for Autodesk Maya
its getting called at the bottom of the script below the class ...

if __name__ == "__main__":
    

    try:
        test_ui.deleteLater()
    except:
        pass
    
    test_ui = smRealCameras()
    
    try:
        test_ui.create()
        test_ui.show()
    except:
        test_ui.deleteLater()
        traceback.print_exc()        

Eric Thivierge

unread,
Feb 15, 2016, 9:11:58 PM2/15/16
to python_in...@googlegroups.com
This rings a bell that I dealt with a few weeks back. I can't find any emails or messages with a quick search but I believe there was some command in maya in reference to the menus, where you have to pass *args, **kwargs and it get's things working. Forget where though. 

--------------------------------------------
Eric Thivierge
http://www.ethivierge.com

--
You received this message because you are subscribed to the Google Groups "Python Programming for Autodesk Maya" group.
To unsubscribe from this group and stop receiving emails from it, send an email to python_inside_m...@googlegroups.com.

Mahmoodreza Aarabi

unread,
Feb 16, 2016, 12:27:45 AM2/16/16
to python_in...@googlegroups.com

Hey man i suggest that use this method for running your window in maya:

class YourClass():
    ....

def getMainWindow():
    mainWindow = QtGui.QApplication.activeWindow()
    while True:
        lastWin = mainWindow.parent()
        if lastWin:
            mainWindow = lastWin
        else:
            break
    return mainWindow

def show():
        win = YourClass(parent=getMainWindow())
        win.show()

about your menu, just i can say put path of userSetup.py in your PYTHONPATH



For more options, visit https://groups.google.com/d/optout.



--


Bests,
madoodia

Justin Israel

unread,
Feb 16, 2016, 1:15:24 AM2/16/16
to python_in...@googlegroups.com
On Tue, Feb 16, 2016 at 6:27 PM Mahmoodreza Aarabi <mado...@gmail.com> wrote:

Hey man i suggest that use this method for running your window in maya:

class YourClass():
    ....

def getMainWindow():
    mainWindow = QtGui.QApplication.activeWindow()
    while True:
        lastWin = mainWindow.parent()
        if lastWin:
            mainWindow = lastWin
        else:
            break
    return mainWindow

def show():
        win = YourClass(parent=getMainWindow())
        win.show()

Is it actually reliable to be trusting the results of activeWindow() to find the main window? What if the active window isn't parented to Maya? 
 

Mahmoodreza Aarabi

unread,
Feb 16, 2016, 1:21:39 AM2/16/16
to python_in...@googlegroups.com
Yes, it is reliable for me so far, and i should say that this will work in nuke and houdini too.
i tested the code in script editor, and importing it in maya, it works. i like to know maybe it run in maya and don't return maya main window as active window?
let me know


For more options, visit https://groups.google.com/d/optout.



--


Bests,
madoodia

md

unread,
Feb 16, 2016, 2:32:03 AM2/16/16
to Python Programming for Autodesk Maya
Ok ... so thanks to everyone for the help ...

Eric ... I did need to have (*args) in the function definition that shows my window.

Justin ... I did end up restructuring my window creation/parenting as follows ...

    def __init__(self, parent=None):
        if parent is None:
            parent = maya_main_window()
            super(smRealCameras, self).__init__(parent)

Mahmoodreza ... you post made me realize that I need to have a specific function to call from usersetup.py (  def window_show(*args): )

The only issue I am running into now is that even though i am doing a try/except to check to see if the window is already created, when I call the script from my menu, it ignores the test and allows me to create multiple instances of the windows. Here is the function to test and show the window.

def sm_real_cam_show(*args):
    try:
        cam_win.deleteLater()
    except:
        pass
    
    cam_win = smRealCameras()
    
    try:
        cam_win.create()
        cam_win.show()
    except:
        cam_win.deleteLater()
        traceback.print_exc()   

 Aside from that issue its working.

Justin Israel

unread,
Feb 16, 2016, 4:02:36 AM2/16/16
to python_in...@googlegroups.com
On Tue, Feb 16, 2016 at 7:21 PM Mahmoodreza Aarabi <mado...@gmail.com> wrote:
Yes, it is reliable for me so far, and i should say that this will work in nuke and houdini too.
i tested the code in script editor, and importing it in maya, it works. i like to know maybe it run in maya and don't return maya main window as active window?
let me know

I'm not saying it isn't functional code. It works just fine under the right conditions. But I am saying its flawed and can return the wrong results, if it were run when the active window isn't parented to Maya. Meaning, it only works if every piece of code running in Maya always makes sure to parent to the main window properly. Here is a reproduction for you:
from PySide import QtGui

def getMainWindow():
    mainWindow = QtGui.QApplication.activeWindow()
    while True:
        lastWin = mainWindow.parent()
        if lastWin:
            mainWindow = lastWin
        else:
            break
    return mainWindow

def printMainWindow():
    print "I think the Maya main window is:", getMainWindow()

d = QtGui.QDialog()
b = QtGui.QPushButton("Print Main Window", d)
b.clicked.connect(printMainWindow)
d.resize(180,100)
d.show()
d.raise_()

Justin
 

Justin Israel

unread,
Feb 16, 2016, 4:08:42 AM2/16/16
to python_in...@googlegroups.com
As much as I hate suggesting globals... the reason this isn't working as expected is because you are always working with a local "cam_win" variable and doing a naked exception handling, so you don't see the real error. If you were to save the object in a global, then you would end up being able to delete the previous one and create a new unique one:

_CAM_WIN = None

def sm_real_cam_show(*args):
    global _CAM_WIN

    if _CAM_WIN is not None:
        try:
            _CAM_WIN.deleteLater()
        except RuntimeError:
            pass
    
    _CAM_WIN = smRealCameras()


 

--
You received this message because you are subscribed to the Google Groups "Python Programming for Autodesk Maya" group.
To unsubscribe from this group and stop receiving emails from it, send an email to python_inside_m...@googlegroups.com.

Mahmoodreza Aarabi

unread,
Feb 16, 2016, 4:34:40 AM2/16/16
to python_in...@googlegroups.com
Justin, got it, i'm on your boat, but i mean if there is a situation that give me wrong result i like to know. why not!

thanks man


For more options, visit https://groups.google.com/d/optout.



--


Bests,
madoodia

Justin Israel

unread,
Feb 16, 2016, 4:40:10 AM2/16/16
to python_in...@googlegroups.com
On Tue, Feb 16, 2016 at 10:34 PM Mahmoodreza Aarabi <mado...@gmail.com> wrote:
Justin, got it, i'm on your boat, but i mean if there is a situation that give me wrong result i like to know. why not!

No problem :-) That's why I gave you a situation that gives a wrong result.
Just lookin out for you, my friend!
 

Mahmoodreza Aarabi

unread,
Feb 16, 2016, 4:47:39 AM2/16/16
to python_in...@googlegroups.com
very good
if i find a problem i will share.

sorry md for distorting your topic
:)

if i find way to create a straightforward way to creating menu with userSetup i will share.
good luck!



For more options, visit https://groups.google.com/d/optout.



--


Bests,
madoodia
Reply all
Reply to author
Forward
0 new messages