Search code examples
buttonpyqtpysidemaya

PySide UI as a Class: button.clicked.connect not connecting


I'm a beginner and trying to wrap a PySide UI script into a class. So far, so good.

However, on the button click, it isn't running the function (or it's not telling me if it is). The print statement does not process. However no error is thrown. It was running fine when I had the non-class-wrapped version.

I know there's something I'm missing here but not sure. Please advise!

PS - this is being done in Maya, but I'm guessing this is more of a PySide thing.

import maya.cmds as cmds
from PySide import QtGui
import maya.OpenMayaUI as mui
import shiboken

class UI(object):
    def __init__(self):

        self.constraintMaster_UI()

    def getMayaWindow(self):
        pointer = mui.MQtUtil.mainWindow() # This is Maya's main window
        QtGui.QMainWindow.styleSheet(shiboken.wrapInstance(long(pointer), QtGui.QWidget))
        return shiboken.wrapInstance(long(pointer), QtGui.QWidget)

    def clickedButton(self):
        print "You just clicked the button!"

    def constraintMaster_UI(self):

        objectName = "pyConstraintMasterWin"

        # Check to see if the UI exists, if so delete it
        if cmds.window("pyConstraintMasterWin", exists = True):
            cmds.deleteUI("pyConstraintMasterWin", wnd = True)

        # Create the window, parent it to the main Maya window (parent -> window).
        # Assign the object name (window name string) to the window
        parent = self.getMayaWindow()
        window = QtGui.QMainWindow(parent)
        window.setObjectName(objectName)
        window.setWindowTitle("Constraint Master")
        window.setMinimumSize(400, 125)
        window.setMaximumSize(400, 125)

        # Create the main widget to contain all the stuff, parent it to the main Widget
        mainWidget = QtGui.QWidget()
        window.setCentralWidget(mainWidget)

        # Create the main vertical layout, add the button and its command
        verticalLayout = QtGui.QVBoxLayout(mainWidget)

        button = QtGui.QPushButton("Create Constraint")
        verticalLayout.addWidget(button)
        button.clicked.connect(self.clickedButton)

        window.show()

UI()

Solution

  • Everything is just perfect but you should know that you are not storing any reference to your main class that is UI. If you do this, after the execution of UI() everything gets destroyed (garbage collected) by Python. This should also close the window immediately after it pops up, but it doesn't because you made the maya window it's parent. If no object exists in the memory, no signals and slots would work. If you are not familiar with garbage collection, refer to this page

    So the solution is to store the reference obj = UI() instead of just UI(), so that the object doesn't get destroyed.