Maya Python - 关于字典和菜单的两个问题

时间:2015-04-18 17:22:27

标签: python maya execute

Q1 - 如何刷新字典以重新显示菜单上显示的目录中的文件?

Q2 - 如何从菜单中执行列为字典文件的脚本?

这是我到目前为止所拥有的

    import os
    import maya.cmds as cmds
    from functools import partial

    # Delete the Menu if it already exists
    if cmds.menu('PadraigsTools', exists = True):
        cmds.deleteUI('PadraigsTools')

    #Creating the GUI
    PadraigsTools=cmds.menu('PadraigsTools', p='MayaWindow', label='PadraigsTools')

    # The Refresh Function / Refresh the scripts
    cmds.menuItem(p=PadraigsTools, l="Refresh" ) #refresh root_dict? 
    cmds.menuItem(p=PadraigsTools, d=1)

    # Browse through Directories
    cmds.menuItem(p=PadraigsTools, l="Change")
    cmds.menuItem(p=PadraigsTools, d=1)

    Python = cmds.menuItem("Python",subMenu=1, label='Python')
    cmds.setParent(Python, menu=True )

    Mel = cmds.menuItem("Mel", subMenu=1, label='Mel', p='PadraigsTools')
    cmds.setParent( Mel, menu=True)

    #TODO Plugins and Other Files Association
    '''Plugins = cmds.menuItem("Plugins", subMenu=1, label='Plugins', p='PadraigsTools')
    cmds.setParent( Plugins, menu=True)

    Other = cmds.menuItem("Other", subMenu=1, label='Other', p='PadraigsTools')
    cmds.setParent( Other, menu=True)'''

    # Searching for Mel and Python Files
    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)
    # Creating a dictionary with given files
    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/OCuinn/Dropbox/Maya Scripts/')

    root_dict = {}
    for item in relative_paths :
        folders, files = relativize(item, ('C:/Users/OCuinn/Dropbox/Maya Scripts/Python Code','C:/Users/OCuinn/Dropbox/Maya Scripts/Mel Code', 'C:/Users/OCuinn/Dropbox/Maya Scripts'))
        if not folders in root_dict:
            root_dict[folders] = []
        root_dict[folders].append(files)

    # call this on every button selection
    def test(filepath, ignore):
        # maya will send "test(name, False)"; we just ignore the 'False'
       print "Here is where I would reload", filepath

    for name in folder_names:
        PadraigsTools = name
        if PadraigsTools:
            PadraigsTools = PadraigsTools.split("/")[-2] # we used trailing slashes
        else:
            PadraigsTools = "root"
        file_names = root_dict[name]
        file_names.sort()
        for fn in file_names: # parent py and mel files to submenus
            if fn.endswith(".py"):

#This is the part I am stuck on I am trying to figure out how to execute the showing fn py or mel file.                                  
                command = "import " + fn[0] + '/' + fn[0] + '.' + fn[0]+ '()'
                cmds.menuItem(label = fn, p="Python", c=command)
            else:
                if fn.endswith(".mel"):
                        cmds.menuItem(label = fn, p="Mel", )

感谢 -padraig

1 个答案:

答案 0 :(得分:0)

如果你真正需要的是一种执行任意文件的方法:

在mel中它刚刚调用source "path/to/file.mel"

在python中,通常的方法是使用runpy module。由于模块可以在导入时运行代码,因此您可以将代码放在文件中,并且当您在.py文件的绝对路径上调用runpy.run_path()时,它将被执行。但是Runpy确实有点神奇,它们不会污染主python命名空间,所以如果你使用的是常见的python

if __name___ = '__main__':
   do_something()

它会破坏,因为从run_path执行的代码不会在__main__范围内。相反,它位于一个名为<run_path>的特殊范围内,所以如果你想做只在这种方式下运行的事情,你可以将它们放入这样的块中:

if __name___ = '<run_path>':
   do_something_for_dynamic_load_only()

为了简化你的代码,你应该首先制作两个函数,一个用于加载mel和另一个python,然后根据扩展选择正确的函数:

import maya.mel as mel
import runpy

def load_mel(filename):
   mel.eval('source "%s"' % filename)

def load_py(filename):
   runpy.run_path(filename)

def load_script(filename):
   ext = filename.split(".")[-1].lower()
   if ext == "mel":
      load_mel(filename)
      return
   if ext == "py":
      load_py(filename)
      return
   cmds.warning("unable to execute file %s" % filename)

然后,您可以使用相同的命令但不同的文件路径构建所有菜单。

一般而言,这种事情应该保留为工具包的“插件”样式扩展,而不是访问功能的主要方式。您无法共享或重复使用这些时尚加载的代码,而是只运行它并获取所发生的一切。另外,每个文件只能获得一个功能,或者至少你需要做很多工作来弄清楚那里有什么。