如何修复Maya PySide脚本中的‘iteration over non-sequence’错误
Let's break down what's causing your error and fix the issues step by step:
Root Cause of the Error
In your testUi.create() method, you're initializing the test class like this:
testIk = test(self)
You're passing self (the testUi instance) to the test class, but test expects a list of Maya transform nodes for its maya_transform_nodes parameter. Since testUi isn't a sequence (like a list or tuple), when set_items() tries to iterate over it, you get the TypeError: iteration over non-sequence.
1. Fix the Argument Passed to test
Since you don't have transform nodes to pass initially, use the default empty list parameter by calling test() without arguments:
testIk = test()
Later, if you want to pass selected nodes, you could do something like test(cmds.ls(selection=True)).
2. Make test a Proper Qt Widget
Your test class isn't inheriting from QtWidgets.QWidget, which means it can't be added to a layout with addWidget(). Update the class definition to inherit from QWidget and initialize the parent class:
class test(QtWidgets.QWidget): def __init__(self, maya_transform_nodes=[], parent=None): super(test, self).__init__(parent) # Initialize the QWidget base class # Replace the separate qWid variable with self (since self is now the widget) self.setMinimumWidth(300) self.setMinimumHeight(300) self.setStyleSheet("border:1px solid rgb(0, 255, 0);") # Rest of your __init__ code...
3. Fix the functools.partial Reference
You're using partial but haven't qualified it with functools. (even though you imported the module). Also, the load_selected method is missing—add a placeholder for it:
# In testUi.create() self.mainButton.clicked.connect(functools.partial(self.load_selected)) # Add this method to testUi class def load_selected(self): # Add your logic here later print("Load Selected button clicked")
4. Fix Python Syntax (for Python 3 Compatibility)
If you're using Maya with Python 3, print path will throw an error. Update it to:
def set_items(self, maya_transform_nodes): for path in maya_transform_nodes: print(path)
Full Corrected Code
from PySide2 import QtGui, QtCore, QtWidgets from shiboken2 import wrapInstance import maya.OpenMaya as om import maya.OpenMayaUI as omui import maya.cmds as cmds import os, functools def getMayaWindow(): pointer = omui.MQtUtil.mainWindow() if pointer is not None: return wrapInstance(long(pointer), QtWidgets.QWidget) class testUi(): def __init__(self): self.window = 'vl_test' self.title = 'Test Remastered' self.size = (1000, 650) def create(self): if cmds.window(self.window, exists=True): cmds.deleteUI(self.window, window=True) self.parentWindow = getMayaWindow() self.mainWindow = QtWidgets.QMainWindow(self.parentWindow) self.mainWindow.setObjectName(self.window) self.mainWindow.setWindowTitle(self.title) self.mainWidget = QtWidgets.QWidget() self.mainWindow.setCentralWidget(self.mainWidget) self.mainLayout = QtWidgets.QFormLayout(self.mainWidget) # Fix: Use default empty list for test class testIk = test() self.mainLayout.addWidget(testIk) self.mainButton = QtWidgets.QPushButton("Load Selected") self.mainLayout.addWidget(self.mainButton) # Fix: Properly reference functools.partial self.mainButton.clicked.connect(functools.partial(self.load_selected)) self.mainWindow.show() def load_selected(self): # Placeholder for button functionality print("Load Selected button clicked") # Fix: Inherit from QtWidgets.QWidget class test(QtWidgets.QWidget): def __init__(self, maya_transform_nodes=[], parent=None): super(test, self).__init__(parent) # Fix: Apply widget properties directly to self self.setMinimumWidth(300) self.setMinimumHeight(300) self.setStyleSheet("border:1px solid rgb(0, 255, 0);") self.items = [] self.transform_move = QtGui.QTransform() self.transform_scale = QtGui.QTransform() self.prev_mouse_pos = QtCore.QPoint(0, 0) self.color = QtGui.QColor(0, 255, 50, 50) self.clicked_color = QtGui.QColor(0, 255, 50, 150) self.right_clicked_color = QtGui.QColor(255, 0, 0, 150) if maya_transform_nodes: self.set_items(maya_transform_nodes) def set_items(self, maya_transform_nodes): # Fix: Python 3 compatible print statement for path in maya_transform_nodes: print(path) v = testUi() v.create()
Why This Works
- We no longer pass a non-sequence object to
set_items, so the loop runs safely. - The
testclass is now a valid QWidget, so it displays correctly in the layout. - All widget properties are applied directly to the
testinstance instead of an unused separate widget. - The button connection uses the correct
functools.partialreference.
内容的提问来源于stack exchange,提问作者Vlad

