【问题标题】:Multiple Paths Traversed and Displayed Filed type in Maya Menu with Python使用 Python 在 Maya 菜单中遍历和显示多条路径
【发布时间】:2015-06-11 14:29:51
【问题描述】:

我是新来的,所以我很清楚这一点,我希望我的问题得到了明确的询问,以帮助我。我正在尝试更改 Brent Tylers Dropbox 脚本,以便我能够在 Python 下列出 Python,在 Mel 下列出 Mel 等等(最终还有插件和其他文件,但现在还没有)

好的,我的目录是这样的:

1.
sf=C:/users/scripts/ a.py + b.mel
pf=C:/users/scripts/Python/c.py
mf=C:/users/scripts/Mel/d.mel

(这些是我的脚本将放入的文件夹)

代码:

absoluteFiles = []
relativeFiles = []
folders = []
allFiles = []
currentFile = ''

for root, dirs, files in os.walk(sf):
    for x in files:
        correct = root.replace('\\', '/')
        currentFile = (correct + '/' + x)
        allFiles.append(currentFile)
        if currentFile.endswith('.mel'):
            relativeFiles.append(currentFile.replace((mf + '/'), ""))
        if currentFile.endswith('.py'):
            relativeFiles.append(currentFile.replace((pf + '/'), ""))

relativeFiles.sort()

for relativeFile in relativeFiles:
    split = relativeFile.split('/')
    fileName = split[-1].split('.')
    i=0
    while i<(len(split)):
        ### Create Folders ###
        if i==0 and len(split) != 1:
            if cmds.menu(split[i] ,ex=1) == 0:
                cmds.menuItem(split[i], p=PadraigsTools, bld=1, sm=1, to=1, l=split[i])
        if i > 0 and i < (len(split)-1):
            if cmds.menu(split[i] ,ex=1) == 0:
                cmds.menuItem(split[i], p=split[i-1], bld=1, sm=1, to=1, l=split[i])

        ### Create .mel Files  ###
        if fileName[-1] == 'mel':
            if i==len(split)-1 and len(split) > 1:
                scriptName = split[-1].split('.')
                temp1 = 'source ' + '"' + sf + '/' + relativeFile + '"; ' + scriptName[0]
                command = '''mel.eval(''' + "'" + temp1 + '''')'''
                cmds.menuItem(split[i], p=split[i-1], c=command, l=split[i])
            if i==len(split)-1 and len(split) == 1:
                scriptName = split[-1].split('.')
                temp1 = 'source ' + '"' + sf + '/' + relativeFile + '"; ' + scriptName[0]
                command = '''mel.eval(''' + "'" + temp1 + '''')'''
                cmds.menuItem(split[i], p=Mel, c=command, l=split[i])

        ### Create .py Files  ###
        if fileName[-1] == 'py':
            if i==len(split)-1 and len(split) > 1:
                command = 'import ' + fileName[0] + '\n' + fileName[0] + '.' + fileName[0]+ '()'
                cmds.menuItem(split[i], p=split[i-1], c=command, l=split[i])
            if i==len(split)-1 and len(split) == 1:
                command = 'import ' + fileName[0] + '\n' + fileName[0] + '.' + fileName[0]+ '()'
                cmds.menuItem(split[i], p=Python, c=command, l=split[i])
        i+=1
  1. 到目前为止,我可以单独打印(sf、pf、mf)到相应的目录,但我不能一次列出所有内容,sf 下的文件根本不会显示。关于创建的文件夹,结果很奇怪。有时我会得到一个重复的文件夹作为子菜单,如果我使用 sf 它会给我 C:/.

  2. 经过数天数小时的研究试图修正此脚本,我没有找到任何答案,包括

from itertools import chain paths = (mf, sf, pf) for path, dirs, files in chain.from_iterable(os.walk(path) for path in paths):

::QUESTION:: 有没有办法我可以将它们巧妙地组合在一起,以便新文件夹在刷新时显示其内容作为子菜单,并且文件将显示并允许我从相应的子菜单中执行它们。

我将不胜感激任何可能的帮助,包括反对票哈哈。请记住,我不希望你用金汤匙把答案交给我,因为我不知道要纠正什么或需要纠正什么:)

非常感谢 -- 帕德莱格

【问题讨论】:

    标签: python menu directory maya


    【解决方案1】:

    您可以做一些事情来简化一些事情。

    首先,最好让它尽可能以数据为驱动,这样如果您的需求发生变化,您就不必重新编写它。这或多或少地完成了您所做的工作,但会将结果收集到字典中,其中键是您提供的根路径,值是相对路径的列表:

    def find_files(root, extensions = ('mel', 'py')):
        def clean_path(*p):
            return "/".join(p).replace('\\', '/')
    
        for root, _, files in os.walk(root):
            used = [f for f in files if f.split(".")[-1] in extensions]
            for u in used:
                yield clean_path(root, u)
    
    def relativize(abs, roots):
        low_roots = map (str.lower, roots) # all lower for comparison
        for root, low_root in zip(roots,low_roots):
            if abs.lower().startswith(low_root):
                return root, abs[len(root):]
        return ("", abs)
    
    
    relative_paths = find_files('c:/users/scripts')
    
    root_dict = {}
    for item in relative_paths :
        folder, file = relativize(item, ('C:/users/scripts/Python/', 'C:/users/scripts/Mel/', 'C:/users/scripts/'))
        if not folder in root_dict:
            root_dict[folder] = []
        root_dict[folder].append(file)
    

    所以现在您有了一个包含一堆根文件夹和相对路径列表的字典(不在您提供的任何相对路径中的文件被键入空字符串并显示为绝对路径)。您可以以非常通用的方式制作菜单,因为它们都采用相同的格式。如果您需要整个列表,可以这样获取:

     results = []
     for each_root in root_dict:
         for relpath in root_dict[each_root]:
             results.append(each_root + relpath)
    

    为了创建实际的菜单,您希望使用单个函数并将其绑定到您创建的每个菜单项的文件名。这是一个有点棘手的话题(更多细节here)。最简单的方法是使用functools.partial 对象,它将一个命令和一堆参数捆绑到一个看起来像函数的对象中:您可以创建一个部分并将其附加到菜单项的命令中,以便它们都使用各自的参数调用相同的函数。这是一个使用上面的变量和菜单栏的简单示例;您可以很容易地了解如何使其适应其他类型的菜单:

    from functools import partial
    
    # call this on every button selection
    def test(filepath, ignore):
        # maya will send "test(name, False)"; we just ignore the 'False'
        print "Here's where I would reload", filepath
    
    example = cmds.window(title = 'example')
    menubar = cmds.menuBarLayout()            
    
    for name in folder_names:
        menuname = name
        if menuname:
            menuname = menuname.split("/")[-2] # we used trailing slashes
        else:
            menuname = "root"
        cmds.menu(label = menuname)
        file_names = root_dict[name]
        file_names.sort()
        for fn in file_names:
            mi = cmds.menuItem(label = fn, command = partial(test, fn))
        cmds.setParent(menubar)
    

    【讨论】:

    • 好吧,所以我有点困惑,但我会尝试解释你的代码 1. find_files = py 和 mel,创建一个干净的路径并将 \\ 更改为 /,所有字符串都更改为更低以进行比较, relative_paths 分配给字典文件中的 find_files。这会查找 mel 和 py 文件并将其附加到名称中,如果不是,它只是进入一个数组
    • 对于菜单,我是保留我的基本布局还是在您的代码下创建另一个。它基本上只是一个普通菜单和带有标签菜单的菜单项。在点击您评论的链接后,我有点掌握了 functools.partial。如果我没记错的话,它会被加载而不是 c =“执行此代码”。哈哈,我想我需要更多帮助
    • 第一个chunk找到根目录下的mel和py文件;第二个获取您关心的子目录列表,并将文件分类到这些子目录下的相对路径中;第三个将其作为字典返回,其中根文件夹作为键,相对路径作为值。最后一部分从字典中创建一个菜单。菜单中的每个项目都运行相同的脚本,但将传递一个反映菜单项的文件路径。脚本的实际加载/卸载/运行应该进入该函数。部分只是捆绑了一个参数和一个没有所有字符串内容的函数
    • 成功将其添加到我的菜单中,但现在所有文件都仅列在其他文件下,而不是按子菜单排序
    • 你可以通过查看字典来检查数据:如果你只得到一个键,你可能会在你提供的相对化路径中有错字
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-10-23
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多