You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何修复Maya PySide脚本中的‘iteration over non-sequence’错误

TypeError: iteration over non-sequence when creating PySide UI in Maya

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 test class is now a valid QWidget, so it displays correctly in the layout.
  • All widget properties are applied directly to the test instance instead of an unused separate widget.
  • The button connection uses the correct functools.partial reference.

内容的提问来源于stack exchange,提问作者Vlad

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.12 04:46:42