Maya Python 使用过程中动态填充gridLayout的实现方法咨询
解决方案
核心原理
Maya的所有UI操作必须在主线程执行,你当前的代码采用同步批量加载逻辑,会阻塞主线程的事件响应队列,导致界面假死直到所有控件加载完成。可以用Maya内置的mc.evalDeferred()方法,把单个控件的加载任务异步调度到主事件循环队列,每次主线程空闲时只执行1个加载任务,剩余时间留给界面响应用户操作,即可实现逐步加载不卡顿的效果。
优化后可运行代码
import maya.cmds as mc import time class dynamicLoad(): def __init__(self): #-- Window self.window_name = 'win' if mc.window(self.window_name, exists=True): mc.deleteUI(self.window_name) self.window = mc.window(self.window_name) #-- Layout layout = mc.formLayout(w=200) self.gridview = mc.gridLayout( numberOfColumns=4, cellWidthHeight=(50, 50), allowEmptyCells=False, autoGrow=True, ) mc.showWindow(self.window_name) #-- 初始化加载参数 self.total_buttons = 20 # 可修改为你实际需要加载的控件总量 self.current_index = 0 # 启动异步加载调度 self.schedule_load() def schedule_load(self): # 所有控件加载完成后终止调度 if self.current_index >= self.total_buttons: return # 低优先级调度加载任务,保证用户交互操作优先执行 mc.evalDeferred(self.load_button, lowPriority=True) def load_button(self): # 这里替换为你实际的图片加载逻辑,time.sleep仅为模拟加载耗时 time.sleep(0.2) mc.setParent(self.gridview) mc.iconTextButton(style='iconAndTextVertical', label=f'test_{self.current_index}') # 更新索引,调度下一个控件的加载 self.current_index += 1 self.schedule_load() dynamicLoad()
关键修改说明
- 移除了同步循环加载逻辑,改用递归调度的方式逐个加载控件,把每个加载任务拆分到不同的UI事件帧执行
evalDeferred的lowPriority=True参数会让加载任务排在用户交互事件之后执行,保证窗口拖动、按钮点击等操作不会被卡顿- 如果需要减少调度开销,也可以在
load_button中一次加载2~3个控件再调度下一轮,平衡加载速度和交互流畅度 - 如果图片资源加载耗时较高,可以配合Python线程池先异步读取图片到内存,再通过
evalDeferred在主线程把资源赋值给iconTextButton,可进一步提升加载速度
内容的提问来源于stack exchange,提问作者Jim de Brouwer
相关产品推荐
相关产品推荐

