多路径遍历并显示在Maya菜单中的归档类型 [英] Multiple Paths Traversed and Displayed Filed type in Maya Menu with Python

查看:197
本文介绍了多路径遍历并显示在Maya菜单中的归档类型的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我是新来的,所以不要犹豫,我希望我的问题明确要求你帮忙。我试图改变Brent Tylers Dropbox脚本,以便我能够在Python下列出Python,Mel在Mel下等等(最终也是插件和其他文件,但现在不是这样)

I'm new here so bare in mind that and I hope my questions are clearly asked for you lot to help me out. I am trying to alter Brent Tylers Dropbox script so that I will be able to list Python under Python, Mel under Mel and so on(eventually plugins and other files too but not for now)

OK,所以我的目录是这样的:

Ok so my directory is like so:

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

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

(These are the folders my scripts will be placed in)

代码:

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:/。

  1. So far I can print out individually (sf, pf, mf) to the corresponding Directory but I cant list out everything at once and the files under sf will not show at all. regarding the folders created it ends up very odd. sometimes i would get a duplicate folder as a submenu and if i use sf it give me C:/.

经过几天和几个小时的研究试图修补脚本我发现没有答案,包括

After days and hours of research trying to mend this script I have found no answer including

from itertools import chain
paths = (mf,sf,pf)
for path,dirs,chain.from_iterable中的文件(路径中路径的os.walk(path)):

:: QUESTION ::
有一种方法,我可以一起把它放在一起,以便新文件夹将在刷新时显示其内容作为子菜单和文件将出现并允许我从相应的子菜单执行它们。

::QUESTION:: Is there a way i can put this together sanely so that new folders will show up with their contents on refresh as a submenu and the files will show up and allow me to execute them from their corresponding submenu.

我会感谢任何可能的帮助,包括投票哈哈。我不想让你给我一个金勺的答案,因为我不知道什么是更正或需要是:)

I would appreciate any help possible including down votes haha. And bare in mind I don't want you to hand me the answer on a golden spoon because I wont know what is corrected or needs to be :)

谢谢伟大的
- Padraig

Thanks Greatly -- Padraig

推荐答案

有一些事情可以简化一些事情。

There's a couple of things you can do to simplify things a bit.

首先,将它设置为数据驱动是一个好主意,因此如果您的需求发生变化,则无需重新写入。这样做或多或少是你所做的,但是将结果收集到字典中,其中键是您提供的根路径,值是相对路径列表:

First, it's a good idea to make this as data-driven as possible so you don't have to re-write it if your needs change. This does more or less what you do, but collects the results into a dictionary where the key are the root paths you supplied and the values are lists of relative paths:

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)

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

So now you have a dictionary with a bunch of root folders and lists of relative paths (files that were not in any relative path you supplied are keyed to empty string and show up as absolute paths). You can make the menus in a very generic way because they are all in the same format. If you need the entire list, you can get it like this:

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

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

For creating the actual menus, you want to use a single function and bind it to the filename for each menu item as you make it. This is a slightly tricky topic (more detail here). The easy way to do this is to use a functools.partial object, which bundles a command and a bunch of arguments into an object which looks like a function: you can create a partial and attach it to the command of your menu items so they all call the same function with their individual arguments. Here's a simple example using the variables from above and a menubar; you can see how to adapt it to other kinds of menus pretty easily:

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)

这篇关于多路径遍历并显示在Maya菜单中的归档类型的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆