Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Autodesk Maya model panel resize event

I'm writing a simple tool menu for Maya, and I'd like to stick it to the border of model panel (perspective).

from PySide import QtCore, QtGui
from maya import OpenMayaUI as omui
from shiboken import wrapInstance

class TestWidget(QtGui.QWidget):
    def __init__(self, parent=None):
        QtGui.QWidget.__init__(self, parent = self.getMayaWindow())

        self.setWindowFlags(QtCore.Qt.Tool | QtCore.Qt.FramelessWindowHint)
        self.setFixedSize(100, 100)

        panelPtr = omui.MQtUtil.findControl('modelPanel4')
        panel = wrapInstance(long(panelPtr), QtGui.QWidget) 

        position =  panel.mapToGlobal(panel.pos())
        self.move(position.x(), position.y() + panel.geometry().height() / 2 - self.geometry().height() / 2)

        mainLayout = QtGui.QVBoxLayout(self)

        button = QtGui.QPushButton('CLOSE')
        button.setFixedSize(80, 80)
        button.clicked.connect(self.deleteLater)

        mainLayout.addWidget(button)

    def getMayaWindow(self):
        omui.MQtUtil.mainWindow()    
        ptr = omui.MQtUtil.mainWindow()
        return wrapInstance(long(ptr), QtGui.QWidget)

w = TestWidget()
w.show()

The main widget is positioned exactly where I want when it is created (horizontally on the left side of model panel, vertically - in the middle of model panel).

I need to reposition it accordingly when the model panel is resized, but model panel does not emit resized() signal. I'd appreciate any advise.

like image 365
Kupnu4 Avatar asked Nov 10 '22 15:11

Kupnu4


1 Answers

I've been trying many things to get this working yesterday. I did some additionnal researches today and came to this topic: cgsociety: Creating a floating button inside the viewport

In case of broken link, this is one of the answer:

You can use geometry but there are some issues with triggering commands based on selection and the undo queue. If you want to go that route, I would suggest looking into zooHud and zooTriggers (Part of the zooToolbox)

If you are wanting actual GUI control parented to the viewport, mel only offers hudslider, hudbutton, and headsUpMessage.

You can also use PyQt and parent in your own custom widgets/layouts or whatever you want using something like this:

import maya.OpenMayaUI as apiUI import sip

from PyQt4 import QtGui

view = apiUI.M3dView()
apiUI.M3dView.getM3dViewFromModelPanel('modelPanel4', view) 
viewWidget = sip.wrapinstance(long(view.widget()), QtCore.QObject)

global myBtn 
myBtn = QtGui.QPushButton(viewWidget)
myBtn.setText('testing!') 
myBtn.move(100, 100) #Relative to top-left corner of viewport myBtn.show()

You can do anything a full qt widget can do with that, so it's extremely flexible. but it would require having PyQt installed, which can be a barrier depending on your tools distribution.

I did a mix of this answer and your code:

from PySide import QtCore, QtGui
from maya import OpenMayaUI as omui
from shiboken import wrapInstance

class CustomQWidget(QtGui.QWidget):    
    def __init__(self, *args, **kwargs):
        QtGui.QWidget.__init__(self, *args, **kwargs)

        mainLayout = QtGui.QVBoxLayout(self)

        closeButton = QtGui.QPushButton('CLOSE')
        closeButton.setFixedSize(80, 40)
        closeButton.clicked.connect(self.deleteLater)

        helloButton = QtGui.QPushButton('HELLO')
        helloButton.setFixedSize(80, 40)
        helloButton.clicked.connect(self.printHello)

        #Trying to fix glitchy background / Doesn't work, why?
        #Is it because layouts don't have background?
        p = self.palette()
        p.setColor(self.backgroundRole(), QtCore.Qt.red)
        self.setPalette(p)
        self.setAttribute(QtCore.Qt.WA_StyledBackground, True)
        ##############################

        mainLayout.addWidget(closeButton)
        mainLayout.addWidget(helloButton)

    def printHello(self):
        print "Hello"

view = omui.M3dView()
omui.M3dView.getM3dViewFromModelPanel('modelPanel4', view) #Given the name of a model panel, 
#get the M3dView used by that panel. If this fails, then a panel with the given name could not be located.
viewWidget = wrapInstance(long(view.widget()), QtGui.QWidget)

position =  viewWidget.mapToGlobal(viewWidget.pos())

w = CustomQWidget(viewWidget)
w.move(0, viewWidget.geometry().height() / 2 - 100 / 2) #Relative to middle-left corner of viewport
w.show()

One of the issue I have it that the background of the widget is glitched: Screenshot

If anyone knows why and how to fix it, I'll edit my answer with pleasure. Else, when running this script from Maya's script editor, the widget follows the panel when it is resized.

like image 169
DrHaze Avatar answered Nov 15 '22 11:11

DrHaze