Problems with MayaMixin and PySide events

maya
python
coding

#1

Hey folk,
Here is the thing

  • I’m working with maya 2017 update 3 and I’ve created a docked QT window via MayaQWidgetDockableMixin.
  • I’ve overriden a QWidget class with it’s own sizes, color, events etc. (I’ve changed it’s color with self.setPalette() method)
  • I’ve added the widget to the Main Docked Window.

The problem is:

  • When I override enterEvent and leaveEvent where I set another cursor and background changes - they have no effect. If I just print smth like event.type() or whatever - it works. I don’t know why it happens. I’ve already tested it out on my Linux OS with the same Maya 2017 Upd3 - the same issue. It’s so stupid problem and really makes me crazy.

Here is my source code, if you have the same version of Maya - try it and tell me how it worked, I have Maya2017 without any updates on my mac and this code works perfect, I’m expecting it happens because of some glitches in update 3 or may be I’m wrong

`from maya.app.general.mayaMixin import MayaQWidgetDockableMixin
 from PySide2 import QtWidgets, QtGui, QtCore
 import maya.cmds as cmds

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

class MyWid(QtWidgets.QWidget):
    def __init__(self, parent = None):
        super(MyWid, self).__init__(parent)

        self.setMinimumSize(50,50)
        self.setMaximumSize(50,50)

        self.bg_color = 49

        self.setAutoFillBackground(True)
        self.p = self.palette()
        self.p.setColor(self.backgroundRole(), QtGui.QColor(self.bg_color,self.bg_color,self.bg_color))
        self.setPalette(self.p)


   def enterEvent(self, event):
        self.setCursor(QtCore.Qt.PointingHandCursor)
        self.p.setColor(self.backgroundRole(), QtGui.QColor(self.bg_color+70,self.bg_color,self.bg_color))
        self.setPalette(self.p)
        return QtWidgets.QWidget.enterEvent(self, event)

    def leaveEvent(self, event):
        self.setCursor(QtCore.Qt.ArrowCursor)
        self.p.setColor(self.backgroundRole(), QtGui.QColor(self.bg_color,self.bg_color,self.bg_color))
        self.setPalette(self.p)
        return QtWidgets.QWidget.leaveEvent(self, event)

    def mouseMoveEvent(self, event):
        self.setCursor(QtCore.Qt.PointingHandCursor)
        return QtWidgets.QWidget.mouseMoveEvent(self, event)




class DialogWidget(MayaQWidgetDockableMixin, QtWidgets.QDialog):
    def __init__(self, parent=None):
        super(DialogWidget, self).__init__(parent=parent)
        self.setObjectName('test_asadsgfasf')
        self.setWindowTitle('test_asadsgfasf')

        self.setLayout(self.createLayout())

    def createLayout(self):

        self.main_layout = QtWidgets.QVBoxLayout()

        self.button = QtWidgets.QPushButton("ASDASDD")
        self.test = MyWid()


        self.main_layout.addWidget(self.button)
        self.main_layout.addWidget(self.test)

        return self.main_layout



def main():
    deleteControl("test_asadsgfasfWorkspaceControl")
    dialogValidatorX = DialogWidget()
    dialogValidatorX.show(dockable=True, area='right', allowedArea = "right",  floating=False)
    cmds.workspaceControl("test_asadsgfasfWorkspaceControl", e=True, ttc=["AttributeEditor", 0], wp="preferred", mw=420)
    dialogValidatorX.raise_()`

#2

I tried it on Maya 2017 Update 3 on Windows 7. The widget changed color when the dialog was not docked. But whenever it was docked, the widget wouldn’t change colors anymore.


#3

That’s the thing ! ))


#4

I noticed that one of my custom widgets also no longer updates when it is docked. Works fine un-docked, but stops updating while docked. I suspect something has changed under the hood with the paint events, or refreshing in PySide2.

The Widgets will update when I click in the Viewport.


#5

Ok, it has been fixed by getting Update 4 for maya 2017 )))


#6

Update 4 did not fix this issue for me. I ended up implementing a quick solution by connecting every signal on my widget to a call to QApplication.processEvents(). Its not exactly elegant but it got the job done.
Here’s the basic code:

from Qt import QtWidgets
from Qt.QtCore import Signal, Slot

def connectToReload(MyWindow):
    cls = MyWindow if isinstance(MyWindow, type) else type(MyWindow)
    signal = type(Signal())
    signals = [name for name in dir(MyWindow) if isinstance(getattr(cls, name), signal)]

    for signal in signals:
        getattr(MyWindow, signal).connect(reloadApp)

@Slot()
def reloadApp(*args, **kwargs):
    app = QtWidgets.QApplication.instance()
    app.processEvents()