尝试使用单独的py文件在Maya中动态填充窗口,以实质上构建模块

时间:2018-05-15 23:20:29

标签: python user-interface maya

所以我正在尝试在Maya中构建一个窗口,其中包含将动态填充的内容。我的文件夹结构是这样的: / scripts / modularMenu /< - 包含:

初始化的.py

modMenu.py

和/ modules /文件夹

在我有的modules文件夹中: modList.py

mod1.py

mod2.py

mod3.py等等。

在modMenu.py中,我告诉Maya绘制窗口,还运行根据modules文件夹的内容填充它的函数,目标是创建新模块,如果标记正确,则填充在窗口。

import maya.cmds as cmds
import sys, os.path
from functools import partial
import modules.modList as mList

def modMenu():
    if (cmds.window('modMenu', exists=True)):
        cmds.deleteUI('modMenu')
    else:
        window = cmds.window( 'modMenu', title="Mod Menu v1.1", iconName='mRig', widthHeight=(400, 800))
        cmds.scrollLayout(width=400, cr=True)
        cmds.columnLayout(adj=True )
        #This all needs to be generated Dynamically.  
        mList.populateWindow()      
        cmds.showWindow( window )

在modList.py中,我有一个类别列表和一个填充窗口的函数。

typeList = ['Type One', 'Type Two', Type Three']

def populateWindow():
    for type in typeList:
        cmds.frameLayout(label = type, collapsable = True, borderStyle = 'etchedIn')
        cmds.text(label = type, al = 'center', height = 15)
        #Need to then go through each module and import the rest of the form here, each form will have to have a tag to determine if it
        #needs to go in this Category or not.  Perhaps the equivalent of...
        #for each mod.py in /modules folder if their tag == type then add
        cmds.setParent( '..' )

我接下来要弄清楚的是,如何安全地将每个单独的mod1.py,mod2.py等的内容导入到这个modList.py文件中,以及两个如何标记每个单独的mod.py文件使其正确放置在菜单系统中。理想情况下,我想在每个mod.py文件中包含一个相同的函数和一个正确标记它的字符串,我可以在modList.py文件中调用,但我不确定如何从这些mod文件中正确导入en masse成功调用该函数。欢迎任何帮助。

2 个答案:

答案 0 :(得分:1)

在一个层面上,这很简单。如果您有一个字符串引用,您可以随时将gui元素添加到Maya布局中,使用setParent()命令告诉Maya新内容的位置。

在这种情况下,你只需要将共享布局传递给一堆函数---它们来自哪里并不重要 - 并让每个函数调用'setParent`来激活布局添加到它。下面是一个如何使用单独的函数而不是单独的模块的例子 - 如果这些不同的函数具有不同的模块起源,它将没有区别。

def button_section(parent):
    cmds.columnLayout(adj=True)
    cmds.frameLayout(label='buttons') 
    cmds.columnLayout(adj=True)
    cmds.rowLayout(nc=2, cw = (200,200))
    cmds.button(label = 'red', backgroundColor=(1,0.5,0.5), width=100)
    cmds.button(label = 'blue', backgroundColor =(0.5, 0.5, 1), width=100)

def text_section(parent):
    cmds.separator()
    cmds.text(label = 'time:')
    cmds.text(label = 'It is currently ' + str(datetime.datetime.now()))
    cmds.text(label = 'main layout is ' + parent)
    cmds.separator()

def object_section(parent):
    cmds.columnLayout(adj=True)
    cmds.frameLayout(label = 'scene')
    cmds.columnLayout(adj=True, rs = 12, columnAttach = ('both', 8) )
    for object in cmds.ls(type='transform'):
        select_the_thing = lambda b: cmds.select(object)
        cmds.button(label = object, c = select_the_thing)   

def create_window(*sections):
    window = cmds.window(title = 'example')
    main_layout = cmds.columnLayout(adj=True)
    for each_section in sections:
        cmds.setParent(main_layout)
        each_section(main_layout)
    cmds.setParent(main_layout)
    cmds.columnLayout(adj=1, columnAttach = ('both', 8))
    cmds.separator()
    cmds.text(label = 'here is a footer')
    cmds.showWindow(window)

create_window(button_section, text_section, object_section)

如果您不熟悉语法,带有*的create_window函数会接受任意数量的参数。在这种情况下,它只是采取三个单独的部分功能。然而,您可以将其写入以获取功能列表。在任何情况下,逻辑都是相同的 - 只需setParent回到主布局,您就可以在布局中添加新内容。

在这个例子中,我将主布局的名称传递给每个不同的布局函数。这很有用,所以你可以做一些事情,比如获得拥有你的布局元素的宽度,或者以递归的方式达到更高的水平。

一般来说,你需要注意的是设计这个,以便不同的部分真正相互独立。如果A部分中的按钮需要知道B部分中复选框的状态,那么事情就会变得很复杂。但是,这将向您展示如何在Maya中构建布局的基础知识。

我会非常小心尝试根据模块文件夹的内容填充菜单 - 如果删除模块但不记得删除它生成的pyc文件,你最终可能会有一个你不期望的虚拟UI部分。最好将代码组织为传统模块,然后使用一个简单的脚本来明确地询问模块。然后,您可以确切地知道在本地安装上会发生什么。

答案 1 :(得分:0)

1 - 你必须使用exec()或" import mod,mod.doIt()",但是什么是"安全"将依赖您的支票

2 - 我不确定理解。你想按编号重新排序吗?     如果没有,我想你可以做一个json存储订单或者可能存储一些元数据