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.