MayaQWidgetDockableMixin closeEvent is not working

Hi all,

I am having a weird issue with the use of MayaQWidgetDockableMixin.
When I am testing my code in Maya 2017, all the signals within are working. However as soon as I tested it out in Maya 2018, while the Gui shows up, it seems that none of the signals are working.

Eg. The use of dockCloseEventTriggered is not called as the Gui is closed.

Wondering if anyone has encountered such issues before?

If I create a button that connects to a function where within the function contains the dockCloseEventTriggered, it works as the button is clicked.

If not, is there a way to ‘force’ the signals to work?

That mixin seems to have quite a few problems. I think the move to workspaceControl instead of dockControl along with the jump to Qt5 / PySide2 kind of broke the hell out of it.

Similar issues:



Hi R.White, I am actually using workspaceControl instead of the dockControl command.
Still, it works for Maya 2017 and not Maya 2018.

In place of this mayaMixin, wondering if you may have any other ideas that I can use it for docking?

On the Qt derived front I honestly don’t know.
When I’ve needed to craft a dockable UI I just used a basic workspaceCommand window and interacted with that.

You could probably craft one of those, get a pointer to the underling QDockWidget and use that as a parent for a regular QWidget panel. But that is honestly pure speculation.

And even so, you’d need to route everything through the workspaceCommand function, so very much a hybrid solution.

Hey, not sure if I can help, but I can certainly paste my functional dockable window, which is in 2018.

class MainWindowDockable(MayaQWidgetDockableMixin, QDialog):
toolname = 'vcToolset'

def __init__(self, parent=None):
    self.deleteInstances()
    super(MainWindowDockable, self).__init__(parent)
    mayaMainWindowPtr = omui.MQtUtil.mainWindow()
    self.mayaMainWindow = wrapInstance(
        long(mayaMainWindowPtr), QMainWindow)
    #self.setObjectName(MainWindowDockable.toolname)
    self.basicTools = None
    self._callback = None
    self.setWindowFlags(Qt.Window)
    self.setWindowTitle('VC Tools')
    self.setMinimumSize(260, 235)
    self.resize(275, 700)
    self.setAttribute(Qt.WA_DeleteOnClose)
    self.layout = QVBoxLayout()
    self.setLayout(self.layout)
    self.setChangeCallback()

    self.setObjectName("VCToolsDockable")


def dockCloseEventTriggered(self):
    self.deleteInstances()
    om.MMessage.removeCallback(self._callback)

def deleteInstances(self):
    mayaMainWindowPtr = omui.MQtUtil.mainWindow()
    mayaMainWindow = wrapInstance(long(mayaMainWindowPtr), QMainWindow)

    for child in mayaMainWindow.children():
        if type(child) == MayaQDockWidget:
            if child.widget().objectName() == MainWindowDockable.toolname:
                mayaMainWindow.removeDockWidget(child)
                child.setParent(None)
                child.deleteLater()

def deleteControl(self, control):
    if cmds.workspaceControl(control, q=True, exists=True):
        cmds.workspaceControl(control, e=True, close=True)
        cmds.deleteUI(control, control=True)

def setChangeCallback(self):
    self._callback = om.MEventMessage.addEventCallback("SelectionChanged", refreshCurVertVal)

All of it might not be relevant to you, but all of it is functional. Maybe there’s a hint in there somewhere.

Hi all, by chance, I stumbled upon this thread - Problems with MayaMixin and PySide events and following the Maya Google link.

It seems that, when my tool is docked, anywhere within Maya, and closing the tool (when it is docked), the dockCloseEventTriggered is actually being called! But no when it is Not docked.

This has definitely stumps me. Even so, the solution does not seems to work for me when it is ‘un-docked’ though.

OH OH OH! I ran into this a while back.

I added some debug code for hide and hideEvent and found that those are getting called instead of close and closeEvent. Once I pointed all the code to the right functionality, it works.

Hi there, thanks for getting back and sorry for my late response.

So, upon replacing dockCloseEventTriggered with the use of hideEvent, it seems to have rectify the issues I was having in Maya 2018! However it is not working when used in Maya 2017. This is weird.

Correct me if I am wrong (since I am not that proficient in Python or PyQt yet), but hideEvent is used if the widgets are hidden right? While it seems to work in my cause, will this cause this any issues (eg. the tool is still running in background etc)?

Seeing that in cases like this, one would presume the use of closeEvent to be the ideal scenario here?

Or am I misunderstanding something here?

I think if you’re closing the window when hideEvent is triggered, then the window won’t be running in the background, but I haven’t tested that yet. I usually follow the pattern of “When you try to open the window, kill the window if it already exists” when calling new windows.

What I’ve got is basically:

class MayaDockWindow(MayaQWidgetDockableMixin, _QtWidgets.QMainWindow):
    ...
    def closeEvent(self, *args):
        super(MayaDockWindow, self).closeEvent(*args)
        self.close()

    def hideEvent(self, *args):
        self.closeEvent(QCloseEvent())
        return