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
答案 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)
然后,您可以使用相同的命令但不同的文件路径构建所有菜单。
一般而言,这种事情应该保留为工具包的“插件”样式扩展,而不是访问功能的主要方式。您无法共享或重复使用这些时尚加载的代码,而是只运行它并获取所发生的一切。另外,每个文件只能获得一个功能,或者至少你需要做很多工作来弄清楚那里有什么。