qt - Evento de cambio de tamaño del panel de modelo de Autodesk Maya
resize pyqt (3)
Estoy escribiendo un menú de herramientas simple para Maya, y me gustaría pegarlo al borde del panel modelo (perspectiva).
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()
El widget principal se coloca exactamente donde yo quiero cuando se crea (horizontalmente en el lado izquierdo del panel del modelo, verticalmente, en el medio del panel del modelo).
Necesito reposicionarlo cuando el panel del modelo cambie de tamaño, pero el panel del modelo no emite la señal de resized()
. Agradecería cualquier consejo.
He estado intentando muchas cosas para que esto funcione ayer. Hice algunas investigaciones adicionales hoy y llegué a este tema: cgsociety: Crear un botón flotante dentro de la ventana gráfica
En caso de enlace roto, esta es una de las respuestas:
Puede usar la geometría, pero hay algunos problemas con la activación de comandos en función de la selección y la cola de deshacer. Si quieres seguir esa ruta, te sugiero que busques zooHud y zooTriggers (Parte de zooToolbox)
Si quieres un control de GUI real relacionado con la ventana gráfica, mel solo ofrece hudslider, hudbutton y headsUpMessage.
También puede usar PyQt y Parent en sus propios widgets / diseños personalizados o lo que quiera utilizando algo como esto:
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()
Puedes hacer todo lo que un widget qt completo puede hacer con eso, por lo que es extremadamente flexible. pero requeriría tener PyQt instalado, que puede ser una barrera dependiendo de la distribución de sus herramientas.
Hice una combinación de esta respuesta y tu código:
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()
Uno de los problemas que tengo es que el fondo del widget está fallado:
Si alguien sabe por qué y cómo solucionarlo, editaré mi respuesta con placer. De lo contrario, al ejecutar este script desde el editor de scripts de Maya, el widget sigue al panel cuando se redimensiona.
Solucioné ese problema, pero no usé Python / PyQt.
El problema en sí es que tu Widget Qt está ahí. No he encontrado una manera de hacerlo no pintar su fondo.
Mi solución fue diferente: obtuve un Qt Layout, inserté todos mis widgets en ese diseño y usé MQtUtil para obtener el QWidget de ese modelPanel''s modelEditor para adjuntarle el "diseño real de Qt".
Advertencia importante que puede hacer que Python no se adapte: Maya no espera que los diseños "no mayas" se vinculen a widgets "reales-mayas" como los editores de modelos. Así que debes escuchar QEvents y descubrir cuándo destruir tu diseño, para que Maya no se estrelle en el intento.
establecer autofillbackground True para corregir el problema de la pintura de fondo