I have a tool that populates a GUI with the lights in a Maya scene, and if the user renames a light in the outliner, I would like the GUI to reflect the new light name. I tried to set up a scriptJob to detect the rename event, but so far it is not working. What am I doing wrong?
import maya.cmds as cmds
import os
import maya.OpenMayaUI as mui
from PySide2 import QtWidgets,QtCore,QtGui
import shiboken2
class widget():
def __init__(self):
self.lights = cmds.ls(type = "VRayLightRectShape")
def clearLayout(self):
layout = self.vertical_layout
if layout is not None:
while layout.count():
item = layout.takeAt(0)
widget = item.widget()
if widget is not None:
widget.setParent(None)
else:
self.clearLayout(item.layout())
def light_button_event(self, text):
print("this is the pressed button's label", text)
def populate_lights(self):
self.clearLayout()
for light in self.lights:
light_btn = QtWidgets.QPushButton(light)
light_btn.clicked.connect(partial(self.light_button_event, light))
self.vertical_layout.addWidget(light_btn)
def light_window(self):
windowName = "lights_palette"
if cmds.window(windowName,exists = True):
cmds.deleteUI(windowName, wnd = True)
pointer = mui.MQtUtil.mainWindow()
parent = shiboken2.wrapInstance(long(pointer),QtWidgets.QWidget)
self.window = QtWidgets.QMainWindow(parent)
self.window.setObjectName(windowName)
self.window.setWindowTitle(windowName)
self.mainWidget = QtWidgets.QWidget()
self.window.setCentralWidget(self.mainWidget)
self.vertical_layout = QtWidgets.QVBoxLayout(self.mainWidget)
self.populate_lights()
self.window.setAttribute(QtCore.Qt.WA_DeleteOnClose)
for light in self.lights:
job = self.myScriptJobID = cmds.scriptJob(p = windowName, nodeNameChanged=[light, self.populate_lights])
self.window.show()
w = widget()
w.light_window()
You are collecting the lights in the constructor. The result is a list of strings which have no connection to the original objects. If I execute the tool here, I can see that the scriptjob called the "populate_lights()" method, but it only reads the existing self.lights list which did not change. So you could simply reread the light list in the populate_lights() method.
If you want to avoid this, you could try PyMel which returns objects instead of strings. You can fill a list of ligths and always get the name of the objects which reflect the current state of the node.