有没有办法在不影响代码的情况下缩进 Python
Is there a way to indent Python without affecting the code
我正在尝试在 Maya 中编写一个用户界面,它变得令人难以置信地混淆了多个级别的父级并且没有缩进。基本代码(没有任何功能)目前大约有 400 行,需要一段时间才能找到我需要的部分。
例如,下面这段代码没有注释:
#Earlier user interface
py.rowColumnLayout( numberOfColumns = 5 )
py.text( label="", width = 1 )
py.text( label="Column 1", enable = False, width = 250 )
py.text( label="", width = 1 )
py.text( label="Column 2" enable = False, width = 250 )
py.text( label="", width = 1 )
py.text( label="" )
py.rowColumnLayout( numberOfColumns = 4 )
py.text( label=" Input data:", align="left" )
py.text( label="" )
py.text( label="" )
py.text( label="" )
py.textField( text = "Text here" )
py.text( label="" )
py.text( label="" )
py.text( label="" )
py.setParent( ".." )
py.text( label="" )
py.rowColumnLayout( numberOfColumns = 4 )
py.rowColumnLayout( numberOfColumns = 5 )
py.radioButton( label = "Read file from path", width = 100 )
py.text( label="" )
py.button( label = "Browse" )
py.text( label="" )
py.button( label = "Validate" )
py.setParent( ".." )
py.text( label="" )
py.text( label="" )
py.text( label="" )
py.setParent( ".." )
py.setParent( ".." )
但是,这是缩进后的样子
py.rowColumnLayout( numberOfColumns = 5 )
py.text( label="", width = 1 )
py.text( label="Column 1", enable = False, width = 250 )
py.text( label="", width = 1 )
py.text( label="Column 2" enable = False, width = 250 )
py.text( label="", width = 1 )
py.text( label="" )
py.rowColumnLayout( numberOfColumns = 4 )
py.text( label=" Input data:", align="left" )
py.text( label="" )
py.text( label="" )
py.text( label="" )
py.textField( text = "Text here" )
py.text( label="" )
py.text( label="" )
py.text( label="" )
py.setParent( ".." )
py.text( label="" )
py.rowColumnLayout( numberOfColumns = 4 )
py.rowColumnLayout( numberOfColumns = 5 )
py.radioButton( label = "Read file from path", width = 100 )
py.text( label="" )
py.button( label = "Browse" )
py.text( label="" )
py.button( label = "Validate" )
py.setParent( ".." )
py.text( label="" )
py.text( label="" )
py.text( label="" )
py.setParent( ".." )
py.setParent( ".." )
有没有什么办法可以让我用缩进来编写它,但让它在执行时忽略它们?我看到这个问题问你是否可以写 python 没有缩进,但我有点需要相反的东西。
注意:某些 py.*
函数的输出值也需要分配给变量,只是尚未分配给变量,因为布局需要先排序。
创建另一个程序来解析和执行您的 script.py
:
parse.py
text = open('script.py').readlines()
text = [i.strip() for i in text]
edit = open('new.py', 'w')
for line in text:
edit.write(line + '\n')
edit.close()
execfile('new.py')
此文件创建了一个修改后的 new.py
,它将被执行。
您可以在执行代码行之前对其进行预处理,如图所示:
mycode = """\
print "something"
print "something else"
print 42
"""
exec('\n'.join(line.lstrip() for line in mycode.splitlines()))
输出:
something
something else
42
甚至可以做成"one-liner":
exec('\n'.join(line.lstrip() for line in """\
print "something"
print "something else"
print 42
""".splitlines()))
您可以通过这种方式将代码保存在一个单独的文件中(这将使您的编辑器能够对其进行语法分析):
文件mycode.py
:
print "something"
print "something else"
var = 42
独立文件版本:
with open('mycode.py') as code:
exec(''.join(line.lstrip() for line in code))
print 'var:', var
输出:
something
something else
var: 42
警告:我应该指出,这些都删除了每行的 all 缩进,这会弄乱任何多行 Python 代码(比如 if/else
) 遇到——这可能会限制它的用处,具体取决于你在做什么。
我能想到两种可能性,允许您直接编写代码而不必从文本中解析它(语法着色完整,没有临时文件)。
第一个是在每行的开头加上一个老生常谈的前缀,就像上面建议的 if True:
或者,等效地,可能是这样的:
# ...
if 'level 1': a = py.text( label="" )
if 'level 2': b = py.rowColumnLayout( numberOfColumns = 4 )
if 'level 3': c = py.rowColumnLayout( numberOfColumns = 5 )
if 'level 4': d = py.radioButton( label = "Read file from path", width = 100 )
# ...
如果您不使用计算结果为 False
的字符串(如 ''
),您可以将这些字符串用作注释,以帮助您记住您正在构建的 GUI 的哪一部分在任何给定的行上(当然,用适当数量的空格填充以确保事情仍然排成一行)。
第二个想法是创建一个包含可调用对象及其参数的容器列表,根据需要格式化该列表,并在最后执行每个容器:
objects = {}
commands = [
# ...
dict( name = 'spam', func = py.text, label="" ),
dict( name = 'ham', func = py.rowColumnLayout, numberOfColumns = 4 ),
dict( name = 'eggs', func = py.rowColumnLayout, numberOfColumns = 5 ),
dict( name = 'beans', func = py.radioButton, label = "Read file from path", width = 100 ),
# ...
]
for d in commands:
objects[ d.pop( 'name' ) ] = d.pop( 'func' )( **d )
使用声明式方法:
interface = [
[py.rowColumnLayout, [], dict(numberOfColumns=5)],
[py.text, [], dict(label="", width=1)],
[py.text, [], dict(label="Column 1", enable=False, width=250)],
...
[py.setParent, [".."], {}],
]
for callable, args, kwargs in interface:
callable(*args, **kwargs)
()
或 []
内的缩进无关紧要,因此您可以随意组织行。
这是像我们这样的技术艺术家在 Maya 中构建 UI 时每天都会遇到的一个很好的用例。
基于 PyMEL UI:
这是内置于 PyMEL 中的。您不必创建上下文管理器。布局命令本身就是上下文管理器。您只需在每个布局命令调用之前添加一个 with
关键字,如下所示:
# Do this when using PyMEL for your UI code
import pymel.core as pm
# ...
with pm.rowColumnLayout( numberOfColumns = 5 ):
pm.text( label="", width = 1 )
pm.text( label="Column 1", enable = False, width = 250 )
pm.text( label="", width = 1 )
pm.text( label="Column 2", enable = False, width = 250 )
pm.text( label="", width = 1 )
pm.text( label="" )
with pm.rowColumnLayout( numberOfColumns = 4 ):
pm.text( label=" Input data:", align="left" )
pm.text( label="" )
pm.text( label="" )
pm.text( label="" )
pm.textField( text = "Text here" )
pm.text( label="" )
pm.text( label="" )
pm.text( label="" )
pm.text( label="" )
with pm.rowColumnLayout( numberOfColumns = 4 ):
with pm.rowColumnLayout( numberOfColumns = 5 ):
pm.radioButton( label = "Read file from path", width = 100 )
pm.text( label="" )
pm.button( label = "Browse" )
pm.text( label="" )
pm.button( label = "Validate" )
pm.text( label="" )
pm.text( label="" )
pm.text( label="" )
基于maya.cmds UI:
一个快速的解决方案是制作一个虚拟上下文管理器。你可以这样做
# Do this when using Maya's cmds for your UI code
import maya.cmds as cmds
# ...
from contextlib import contextmanager
@contextmanager
def neat_indent():
# OPTIONAL: This is also an opportunity to do something before the block of code runs!
try:
# During this is where your indented block will execute
# Leave it empty
yield
finally:
# OPTIONAL: This is where you can write code that executes AFTER your indented block executes.
pass
这样您的代码就不必更改太多。只需在每个预期缩进的开头添加带有 with
关键字的上下文管理器函数!
cmds.rowColumnLayout( numberOfColumns = 5 )
with neat_indent():
cmds.text( label="", width = 1 )
cmds.text( label="Column 1", enable = False, width = 250 )
cmds.text( label="", width = 1 )
cmds.text( label="Column 2", enable = False, width = 250 )
cmds.text( label="", width = 1 )
cmds.text( label="" )
cmds.rowColumnLayout( numberOfColumns = 4 )
with neat_indent():
cmds.text( label=" Input data:", align="left" )
cmds.text( label="" )
cmds.text( label="" )
cmds.text( label="" )
cmds.textField( text = "Text here" )
cmds.text( label="" )
cmds.text( label="" )
cmds.text( label="" )
cmds.setParent( ".." )
cmds.text( label="" )
cmds.rowColumnLayout( numberOfColumns = 4 )
with neat_indent():
cmds.rowColumnLayout( numberOfColumns = 5 )
with neat_indent():
cmds.radioButton( label = "Read file from path", width = 100 )
cmds.text( label="" )
cmds.button( label = "Browse" )
cmds.text( label="" )
cmds.button( label = "Validate" )
cmds.setParent( ".." )
cmds.text( label="" )
cmds.text( label="" )
cmds.text( label="" )
cmds.setParent( ".." )
cmds.setParent( ".." )
我们创建的上下文管理器 neat_indent()
还让您有机会编写封装缩进块的代码。这里的一个实际例子是,在每个缩进的末尾,你发现自己写着 py.setParent("..")
。您可以将其放入上下文管理器的 finally
部分:
from contextlib import contextmanager
@contextmanager
def neat_indent(parent=None):
# OPTIONAL: This is also an opportunity to do something before the block of code runs!
try:
# During this is where your indented block will execute
# Leave it empty
yield
finally:
# OPTIONAL: This is where you can write code that executes AFTER your indented block executes.
if parent:
cmds.setParent(parent)
您的代码现在会更有意义:
cmds.rowColumnLayout( numberOfColumns = 5 )
with neat_indent(".."):
cmds.text( label="", width = 1 )
cmds.text( label="Column 1", enable = False, width = 250 )
cmds.text( label="", width = 1 )
cmds.text( label="Column 2", enable = False, width = 250 )
cmds.text( label="", width = 1 )
cmds.text( label="" )
cmds.rowColumnLayout( numberOfColumns = 4 )
with neat_indent(".."):
cmds.text( label=" Input data:", align="left" )
cmds.text( label="" )
cmds.text( label="" )
cmds.text( label="" )
cmds.textField( text = "Text here" )
cmds.text( label="" )
cmds.text( label="" )
cmds.text( label="" )
cmds.text( label="" )
cmds.rowColumnLayout( numberOfColumns = 4 )
with neat_indent(".."):
cmds.rowColumnLayout( numberOfColumns = 5 )
with neat_indent(".."):
cmds.radioButton( label = "Read file from path", width = 100 )
cmds.text( label="" )
cmds.button( label = "Browse" )
cmds.text( label="" )
cmds.button( label = "Validate" )
cmds.text( label="" )
cmds.text( label="" )
cmds.text( label="" )
上下文管理器很强大。在这个 post 中,我使用了 contextlib
标准库模块中的 contextmanager
装饰器。您可以阅读有关此技术的信息 here. About with
in general here。
此外,正是出于这个目的(目的之一),使 UI 在 Maya 中的开发更清洁和更 Pythonic @theodox 创建了 mGui 模块。看看吧。
@Kartik 的回答很好地涵盖了基础。我要指出的是,您可以通过允许上下文管理器在线声明布局(rowLayout、columnLayout 等)来进一步清理布局代码,这使它变得更加容易:
class uiCtx(object):
'''
quickie layouthelper: automatically setParents after a layout is finished
'''
def __init__(self, uiClass, *args, **kwargs):
self.Control = uiClass(*args, **kwargs)
def __enter__(self):
return self
def __exit__(self, tb, val, traceback):
cmds.setParent("..")
def __repr__(self):
return self.Control
会在遇到时调用 maya.cmds 布局函数,然后在缩进块的末尾关闭父级,因此您可以像此代码段中一样进行布局调用
with uiCtx(cmds.rowLayout, **layout_options) as widget:
self.Toggle = cmds.checkBox('', v = self.Module.enabled, cc = self._state_changed)
with uiCtx(cmds.columnLayout, w=self.COLUMNS[1], cal='left') as details:
cmds.text(l = self.ModuleKey, fn = "boldLabelFont")
cmds.text(l = self.Module.path, fn = "smallObliqueLabelFont")
cmds.button("edit", c=self._edit)
cmds.button("show", c=self._show)
return widget
将 __repr__
添加到 uiCtx
后,您就可以像普通 Maya 布局命令那样将其视为返回字符串,因此在该示例中可以查询 'widget'通常的方式。
整个就是up on GitHub to see it in context. As Kartik also pointed out there's a more elaborate declarative UI option in the form of mGui,实际上是这样的:
with gui.Window('window', title = 'fred') as example_window:
with BindingContext() as bind_ctx:
with VerticalForm('main') as main:
Text(None, label = "The following items don't have vertex colors")
lists.VerticalList('lister' ).Collection < bind() < bound
with HorizontalStretchForm('buttons'):
Button('refresh', l='Refresh')
Button('close', l='Close')
# show the window
example_window.show()
还有一些 maya 布局相关信息 here
我已经用了很多年了,效果非常好:
if True:
# Indented code.
print("This entire code block is indented.")
我正在尝试在 Maya 中编写一个用户界面,它变得令人难以置信地混淆了多个级别的父级并且没有缩进。基本代码(没有任何功能)目前大约有 400 行,需要一段时间才能找到我需要的部分。
例如,下面这段代码没有注释:
#Earlier user interface
py.rowColumnLayout( numberOfColumns = 5 )
py.text( label="", width = 1 )
py.text( label="Column 1", enable = False, width = 250 )
py.text( label="", width = 1 )
py.text( label="Column 2" enable = False, width = 250 )
py.text( label="", width = 1 )
py.text( label="" )
py.rowColumnLayout( numberOfColumns = 4 )
py.text( label=" Input data:", align="left" )
py.text( label="" )
py.text( label="" )
py.text( label="" )
py.textField( text = "Text here" )
py.text( label="" )
py.text( label="" )
py.text( label="" )
py.setParent( ".." )
py.text( label="" )
py.rowColumnLayout( numberOfColumns = 4 )
py.rowColumnLayout( numberOfColumns = 5 )
py.radioButton( label = "Read file from path", width = 100 )
py.text( label="" )
py.button( label = "Browse" )
py.text( label="" )
py.button( label = "Validate" )
py.setParent( ".." )
py.text( label="" )
py.text( label="" )
py.text( label="" )
py.setParent( ".." )
py.setParent( ".." )
但是,这是缩进后的样子
py.rowColumnLayout( numberOfColumns = 5 )
py.text( label="", width = 1 )
py.text( label="Column 1", enable = False, width = 250 )
py.text( label="", width = 1 )
py.text( label="Column 2" enable = False, width = 250 )
py.text( label="", width = 1 )
py.text( label="" )
py.rowColumnLayout( numberOfColumns = 4 )
py.text( label=" Input data:", align="left" )
py.text( label="" )
py.text( label="" )
py.text( label="" )
py.textField( text = "Text here" )
py.text( label="" )
py.text( label="" )
py.text( label="" )
py.setParent( ".." )
py.text( label="" )
py.rowColumnLayout( numberOfColumns = 4 )
py.rowColumnLayout( numberOfColumns = 5 )
py.radioButton( label = "Read file from path", width = 100 )
py.text( label="" )
py.button( label = "Browse" )
py.text( label="" )
py.button( label = "Validate" )
py.setParent( ".." )
py.text( label="" )
py.text( label="" )
py.text( label="" )
py.setParent( ".." )
py.setParent( ".." )
有没有什么办法可以让我用缩进来编写它,但让它在执行时忽略它们?我看到这个问题问你是否可以写 python 没有缩进,但我有点需要相反的东西。
注意:某些 py.*
函数的输出值也需要分配给变量,只是尚未分配给变量,因为布局需要先排序。
创建另一个程序来解析和执行您的 script.py
:
parse.py
text = open('script.py').readlines()
text = [i.strip() for i in text]
edit = open('new.py', 'w')
for line in text:
edit.write(line + '\n')
edit.close()
execfile('new.py')
此文件创建了一个修改后的 new.py
,它将被执行。
您可以在执行代码行之前对其进行预处理,如图所示:
mycode = """\
print "something"
print "something else"
print 42
"""
exec('\n'.join(line.lstrip() for line in mycode.splitlines()))
输出:
something
something else
42
甚至可以做成"one-liner":
exec('\n'.join(line.lstrip() for line in """\
print "something"
print "something else"
print 42
""".splitlines()))
您可以通过这种方式将代码保存在一个单独的文件中(这将使您的编辑器能够对其进行语法分析):
文件mycode.py
:
print "something"
print "something else"
var = 42
独立文件版本:
with open('mycode.py') as code:
exec(''.join(line.lstrip() for line in code))
print 'var:', var
输出:
something
something else
var: 42
警告:我应该指出,这些都删除了每行的 all 缩进,这会弄乱任何多行 Python 代码(比如 if/else
) 遇到——这可能会限制它的用处,具体取决于你在做什么。
我能想到两种可能性,允许您直接编写代码而不必从文本中解析它(语法着色完整,没有临时文件)。
第一个是在每行的开头加上一个老生常谈的前缀,就像上面建议的 if True:
或者,等效地,可能是这样的:
# ...
if 'level 1': a = py.text( label="" )
if 'level 2': b = py.rowColumnLayout( numberOfColumns = 4 )
if 'level 3': c = py.rowColumnLayout( numberOfColumns = 5 )
if 'level 4': d = py.radioButton( label = "Read file from path", width = 100 )
# ...
如果您不使用计算结果为 False
的字符串(如 ''
),您可以将这些字符串用作注释,以帮助您记住您正在构建的 GUI 的哪一部分在任何给定的行上(当然,用适当数量的空格填充以确保事情仍然排成一行)。
第二个想法是创建一个包含可调用对象及其参数的容器列表,根据需要格式化该列表,并在最后执行每个容器:
objects = {}
commands = [
# ...
dict( name = 'spam', func = py.text, label="" ),
dict( name = 'ham', func = py.rowColumnLayout, numberOfColumns = 4 ),
dict( name = 'eggs', func = py.rowColumnLayout, numberOfColumns = 5 ),
dict( name = 'beans', func = py.radioButton, label = "Read file from path", width = 100 ),
# ...
]
for d in commands:
objects[ d.pop( 'name' ) ] = d.pop( 'func' )( **d )
使用声明式方法:
interface = [
[py.rowColumnLayout, [], dict(numberOfColumns=5)],
[py.text, [], dict(label="", width=1)],
[py.text, [], dict(label="Column 1", enable=False, width=250)],
...
[py.setParent, [".."], {}],
]
for callable, args, kwargs in interface:
callable(*args, **kwargs)
()
或 []
内的缩进无关紧要,因此您可以随意组织行。
这是像我们这样的技术艺术家在 Maya 中构建 UI 时每天都会遇到的一个很好的用例。
基于 PyMEL UI:
这是内置于 PyMEL 中的。您不必创建上下文管理器。布局命令本身就是上下文管理器。您只需在每个布局命令调用之前添加一个 with
关键字,如下所示:
# Do this when using PyMEL for your UI code
import pymel.core as pm
# ...
with pm.rowColumnLayout( numberOfColumns = 5 ):
pm.text( label="", width = 1 )
pm.text( label="Column 1", enable = False, width = 250 )
pm.text( label="", width = 1 )
pm.text( label="Column 2", enable = False, width = 250 )
pm.text( label="", width = 1 )
pm.text( label="" )
with pm.rowColumnLayout( numberOfColumns = 4 ):
pm.text( label=" Input data:", align="left" )
pm.text( label="" )
pm.text( label="" )
pm.text( label="" )
pm.textField( text = "Text here" )
pm.text( label="" )
pm.text( label="" )
pm.text( label="" )
pm.text( label="" )
with pm.rowColumnLayout( numberOfColumns = 4 ):
with pm.rowColumnLayout( numberOfColumns = 5 ):
pm.radioButton( label = "Read file from path", width = 100 )
pm.text( label="" )
pm.button( label = "Browse" )
pm.text( label="" )
pm.button( label = "Validate" )
pm.text( label="" )
pm.text( label="" )
pm.text( label="" )
基于maya.cmds UI:
一个快速的解决方案是制作一个虚拟上下文管理器。你可以这样做
# Do this when using Maya's cmds for your UI code
import maya.cmds as cmds
# ...
from contextlib import contextmanager
@contextmanager
def neat_indent():
# OPTIONAL: This is also an opportunity to do something before the block of code runs!
try:
# During this is where your indented block will execute
# Leave it empty
yield
finally:
# OPTIONAL: This is where you can write code that executes AFTER your indented block executes.
pass
这样您的代码就不必更改太多。只需在每个预期缩进的开头添加带有 with
关键字的上下文管理器函数!
cmds.rowColumnLayout( numberOfColumns = 5 )
with neat_indent():
cmds.text( label="", width = 1 )
cmds.text( label="Column 1", enable = False, width = 250 )
cmds.text( label="", width = 1 )
cmds.text( label="Column 2", enable = False, width = 250 )
cmds.text( label="", width = 1 )
cmds.text( label="" )
cmds.rowColumnLayout( numberOfColumns = 4 )
with neat_indent():
cmds.text( label=" Input data:", align="left" )
cmds.text( label="" )
cmds.text( label="" )
cmds.text( label="" )
cmds.textField( text = "Text here" )
cmds.text( label="" )
cmds.text( label="" )
cmds.text( label="" )
cmds.setParent( ".." )
cmds.text( label="" )
cmds.rowColumnLayout( numberOfColumns = 4 )
with neat_indent():
cmds.rowColumnLayout( numberOfColumns = 5 )
with neat_indent():
cmds.radioButton( label = "Read file from path", width = 100 )
cmds.text( label="" )
cmds.button( label = "Browse" )
cmds.text( label="" )
cmds.button( label = "Validate" )
cmds.setParent( ".." )
cmds.text( label="" )
cmds.text( label="" )
cmds.text( label="" )
cmds.setParent( ".." )
cmds.setParent( ".." )
我们创建的上下文管理器 neat_indent()
还让您有机会编写封装缩进块的代码。这里的一个实际例子是,在每个缩进的末尾,你发现自己写着 py.setParent("..")
。您可以将其放入上下文管理器的 finally
部分:
from contextlib import contextmanager
@contextmanager
def neat_indent(parent=None):
# OPTIONAL: This is also an opportunity to do something before the block of code runs!
try:
# During this is where your indented block will execute
# Leave it empty
yield
finally:
# OPTIONAL: This is where you can write code that executes AFTER your indented block executes.
if parent:
cmds.setParent(parent)
您的代码现在会更有意义:
cmds.rowColumnLayout( numberOfColumns = 5 )
with neat_indent(".."):
cmds.text( label="", width = 1 )
cmds.text( label="Column 1", enable = False, width = 250 )
cmds.text( label="", width = 1 )
cmds.text( label="Column 2", enable = False, width = 250 )
cmds.text( label="", width = 1 )
cmds.text( label="" )
cmds.rowColumnLayout( numberOfColumns = 4 )
with neat_indent(".."):
cmds.text( label=" Input data:", align="left" )
cmds.text( label="" )
cmds.text( label="" )
cmds.text( label="" )
cmds.textField( text = "Text here" )
cmds.text( label="" )
cmds.text( label="" )
cmds.text( label="" )
cmds.text( label="" )
cmds.rowColumnLayout( numberOfColumns = 4 )
with neat_indent(".."):
cmds.rowColumnLayout( numberOfColumns = 5 )
with neat_indent(".."):
cmds.radioButton( label = "Read file from path", width = 100 )
cmds.text( label="" )
cmds.button( label = "Browse" )
cmds.text( label="" )
cmds.button( label = "Validate" )
cmds.text( label="" )
cmds.text( label="" )
cmds.text( label="" )
上下文管理器很强大。在这个 post 中,我使用了 contextlib
标准库模块中的 contextmanager
装饰器。您可以阅读有关此技术的信息 here. About with
in general here。
此外,正是出于这个目的(目的之一),使 UI 在 Maya 中的开发更清洁和更 Pythonic @theodox 创建了 mGui 模块。看看吧。
@Kartik 的回答很好地涵盖了基础。我要指出的是,您可以通过允许上下文管理器在线声明布局(rowLayout、columnLayout 等)来进一步清理布局代码,这使它变得更加容易:
class uiCtx(object):
'''
quickie layouthelper: automatically setParents after a layout is finished
'''
def __init__(self, uiClass, *args, **kwargs):
self.Control = uiClass(*args, **kwargs)
def __enter__(self):
return self
def __exit__(self, tb, val, traceback):
cmds.setParent("..")
def __repr__(self):
return self.Control
会在遇到时调用 maya.cmds 布局函数,然后在缩进块的末尾关闭父级,因此您可以像此代码段中一样进行布局调用
with uiCtx(cmds.rowLayout, **layout_options) as widget:
self.Toggle = cmds.checkBox('', v = self.Module.enabled, cc = self._state_changed)
with uiCtx(cmds.columnLayout, w=self.COLUMNS[1], cal='left') as details:
cmds.text(l = self.ModuleKey, fn = "boldLabelFont")
cmds.text(l = self.Module.path, fn = "smallObliqueLabelFont")
cmds.button("edit", c=self._edit)
cmds.button("show", c=self._show)
return widget
将 __repr__
添加到 uiCtx
后,您就可以像普通 Maya 布局命令那样将其视为返回字符串,因此在该示例中可以查询 'widget'通常的方式。
整个就是up on GitHub to see it in context. As Kartik also pointed out there's a more elaborate declarative UI option in the form of mGui,实际上是这样的:
with gui.Window('window', title = 'fred') as example_window:
with BindingContext() as bind_ctx:
with VerticalForm('main') as main:
Text(None, label = "The following items don't have vertex colors")
lists.VerticalList('lister' ).Collection < bind() < bound
with HorizontalStretchForm('buttons'):
Button('refresh', l='Refresh')
Button('close', l='Close')
# show the window
example_window.show()
还有一些 maya 布局相关信息 here
我已经用了很多年了,效果非常好:
if True:
# Indented code.
print("This entire code block is indented.")