python + maya ui?按钮落后于别人

时间:2014-04-24 15:37:44

标签: python maya

我不太确定我在哪里出错了。我是python GUI制作方面的玛雅场景的新手。在我的代码中搞砸了什么?我希望底部按钮跨越对话框的整个宽度。我认为布局是正确的,但是当你运行代码时,按钮似乎被卡在某些列后面。

'''
John Martini
Quad Sphere 1.0

More info on how to use it can be found at 
http://JokerMartini.com
'''

import maya.cmds as cmds
import random

class jmQuadSphere(object):

    def __init__(self):
        pass

    def show(self):
        self.GUI()

    def GUI(self):
        #check to see if our window exists
        window = "jmQuadSphere"
        if cmds.window(window, exists=True):
            cmds.deleteUI(window)

        # create our window
        window = cmds.window("jmQuadSphere", title = "Quad Sphere", mnb = False, mxb = False, sizeable = False)

        cmds.setParent(window)
        # Row layout that specifies 3 columns and the width for each column.
        cmds.rowColumnLayout('rlOpts', nc=2, cw=[(1,90),(2,90)])
        # Each button after the row layout is automatically insterted into the columns numerically
        cmds.text( label='Radius:', align='left' )
        cmds.floatField('spRadius', minValue=0, maxValue=999999999, value=10, precision=3, step=.01 )

        cmds.text( label='Height:', align='left' )
        cmds.floatField('spHeight', minValue=0, maxValue=999999999, value=10, precision=3, step=.01 )

        cmds.text( label='Width:', align='left' )
        cmds.floatField('spWidth', minValue=0, maxValue=999999999, value=10, precision=3, step=.01 )

        cmds.text( label='Depth:', align='left' )
        cmds.floatField('spDepth', minValue=0, maxValue=999999999, value=10, precision=3, step=.01 )

        cmds.text( label='Height Segs:', align='left' )
        cmds.intField('spHeightSegs', minValue=0, maxValue=999999999, value=4 )

        cmds.text( label='Width Segs:', align='left' )
        cmds.intField('spWidthSegs', minValue=0, maxValue=999999999, value=4 )

        cmds.text( label='Depth Segs:', align='left' )
        cmds.intField('spDepthSegs', minValue=0, maxValue=999999999, value=4 )

        cmds.text( label='Roundness:', align='left' )
        cmds.floatField('spRoundness', minValue=0, maxValue=100, value=100, precision=2, step=.01 )

        cmds.text( label='Flatness:', align='left' )
        cmds.floatField('spFlatness', minValue=0, maxValue=100, value=0, precision=2, step=.01 )


        cmds.setParent(window)
        cmds.rowColumnLayout('rlRun', nc=1)

        cmds.button('btnCreateQuadSphere', l="Create", w=180, h=30)

        # show window
        cmds.showWindow(window)

#execute tool
jmQuadSphere().show()

cmds.scriptEditorInfo(ch=True)

截图:

screenshot

2 个答案:

答案 0 :(得分:2)

Gawd我讨厌Maya的布局。 formLayout一路走来! (如果不是QT)

看起来rowColumnLayout是第一列的宽度,即使它不是第一列{child}的孩子。您可以明确设置宽度:

rowColumnLayout

考虑到您只有一列,当您只能使用cmds.setParent(window) cmds.rowColumnLayout('rlRun', nc=1) cmds.button('btnCreateQuadSphere', l="Create", w=180, h=30) 时,没有理由使用rowColumnLayout

columnLayout

截图:

enter image description here

答案 1 :(得分:1)

Maya的UI系统创建后面有一套逻辑。一旦您习惯了布局和控件层次结构背后的基本原理,它将以非常可控和可预测的方式运行良好。

我使用过PyQT(PySide)和Maya的UI框架,但我发现Maya并不笨重。实际上,Maya的UI系统比PyQT更加简化和轻松。获取相同的UI布局和功能需要较少的代码行。当然,QT的最大优势是跨平台和跨软件的独立性。仅这一点就足以说明它了。

如果您不打算将代码移植到Maya之外,那么使用Maya UI的好处在于,命令以及代码将始终在未来尽可能得到支持。

以最近的Maya 2017为例。从Maya 2016开始,UI框架被切换到PyQT 5和PySide 2.这将破坏为PyQt4和PySide 1编写的代码。但是,如果您使用Maya的UI系统编写了UI,它将继续正常工作。当然,修改基于PyQT的代码以使所需的更改与新框架兼容可能就像在编辑器中搜索和替换一样简单,但仍有可能破坏某些内容。

对于使用columnLayoutrowLayout的Maya用户界面的这种方式,您需要在创建组件的级别上保留标签(请原谅双关语)。

rowColumnLayout令人困惑,因为同时对行和列进行了大量的控制。我通常使用主columnLayout(垂直向下移动UI),当我需要多个水平布局的控件时,我将仅使用rowLayout作为该行。

setParent是你的朋友。使用setParent将您的UI创建“光标/指针”放回到所需的UI层次结构下。

在我的第一个示例代码中,我展示了如何使用变量来存储布局的名称。这样,我可以轻松地在组件的UI层次结构中的不同级别之间跳转。

UI screenshot 1

运行我的以下代码块,看看我们对布局的灵活性。对于Maya中的UI需要做的就足够了。

import maya.cmds as mc
def buildUI():
  winName = 'myWindow'
  winWidth = 200 # set a target width and reference this when you specify width
  if mc.window(winName, exists=True):
      mc.deleteUI(winName)
  mc.window(winName, width=winWidth, title='Test Window')
  # i always have keep a reference to the main columnLayout
  mainCL = mc.columnLayout() 
  mc.text(label='text row 1')

  # tmpRowWidth controls the width of my columns in the rowLayout
  # with reference to winWidth
  tmpRowWidth = [winWidth*0.3, winWidth*0.7]
  mc.rowLayout(numberOfColumns=2, columnWidth2=tmpRowWidth)
  # at this point our UI pointer is under the rowLayout
  mc.text(label='row column1', align='center', width=tmpRowWidth[0])
  mc.button(label='column 2', width=tmpRowWidth[1])
  # we've used up number of children components, if you add 1 more, 
  # Maya will throw an error
  # now to move our pointer back up the hierarchy, 
  # which is our main columnLayout, mainCL
  mc.setParent('..') # also can use mc.setParent(mainCL)

  tmpRowWidth = [winWidth*0.5, winWidth*0.5]
  mc.rowLayout(numberOfColumns=2, columnWidth2=tmpRowWidth)
  mc.text(label='row column1', align='center', width=tmpRowWidth[0])
  mc.button(label='column 2', width=tmpRowWidth[1])
  mc.setParent('..')

  tmpRowWidth = [winWidth*0.7, winWidth*0.3]
  mc.rowLayout(numberOfColumns=2, columnWidth2=tmpRowWidth)
  mc.text(label='row column1', align='center', width=tmpRowWidth[0])
  mc.button(label='column 2', width=tmpRowWidth[1])
  mc.setParent('..')

  mc.text(label='text row 3')

  tmpWidth = [winWidth*0.3, winWidth*0.5, winWidth*0.2]
  mc.textFieldButtonGrp(label='txt field', w=winWidth, columnWidth3=tmpWidth, buttonLabel='okay')
  mc.button('full width button', width=winWidth)

  mc.showWindow(winName)
  mc.window(winName, e=True, width=winWidth, height=1)
  return
buildUI()

通过稍微改变代码,我可以实现以下目标: UI Screenshot 2

原始布局仍在那里,但现在我已将其放入更大rowLayout的列中。

以下是生成此内容的代码。

import maya.cmds as mc
def buildUI():
  winName = 'myWindow'
  winWidth = 400 # set a target width and reference this when you specify width
  if mc.window(winName, exists=True):
      mc.deleteUI(winName)
  mc.window(winName, width=winWidth, title='Test Window')
  # i always have keep a reference to the main columnLayout
  mainCL = mc.columnLayout() 
  mainRLWidth = [winWidth*0.6, winWidth*0.4]
  mainRL = mc.rowLayout(w=winWidth, numberOfColumns=2, columnWidth2=mainRLWidth, rowAttach=(2, 'top', 0))
  mc.columnLayout(w=mainRLWidth[0]) # create a columnLayout under the first row of mainRL
  mc.text(label='mainRL column 1', font='boldLabelFont')
  mc.text(label='')
  mc.text(label='text row 1')

  # tmpRowWidth controls the width of my columns in the rowLayout
  # with reference to winWidth
  tmpRowWidth = [mainRLWidth[0]*0.3, mainRLWidth[0]*0.7]
  mc.rowLayout(numberOfColumns=2, columnWidth2=tmpRowWidth)
  # at this point our UI pointer is under the rowLayout
  mc.text(label='row column1', align='center', width=tmpRowWidth[0])
  mc.button(label='column 2', width=tmpRowWidth[1])
  # we've used up number of children components, if you add 1 more, 
  # Maya will throw an error
  # now to move our pointer back up the hierarchy, 
  # which is our main rowLayout, mainRL
  mc.setParent('..') # also can use mc.setParent(mainRL)

  tmpRowWidth = [mainRLWidth[0]*0.5, mainRLWidth[0]*0.5]
  mc.rowLayout(numberOfColumns=2, columnWidth2=tmpRowWidth)
  mc.text(label='row column1', align='center', width=tmpRowWidth[0])
  mc.button(label='column 2', width=tmpRowWidth[1])
  mc.setParent('..')

  tmpRowWidth = [mainRLWidth[0]*0.7, mainRLWidth[0]*0.3]
  mc.rowLayout(numberOfColumns=2, columnWidth2=tmpRowWidth)
  mc.text(label='row column1', align='center', width=tmpRowWidth[0])
  mc.button(label='column 2', width=tmpRowWidth[1])
  mc.setParent('..')

  mc.text(label='text row 3')
  tmpWidth = [mainRLWidth[0]*0.3, mainRLWidth[0]*0.5, mainRLWidth[0]*0.2]
  mc.textFieldButtonGrp(label='txt field', w=mainRLWidth[0], columnWidth3=tmpWidth, buttonLabel='okay')
  mc.button('full row width button', width=mainRLWidth[0])
  mc.setParent('..') # this will exit the rowLayout back to the mainRL, same as mc.setParent(mainRL)

  mc.columnLayout(width=mainRLWidth[1]) # start another vertical layout
  mc.text(label='mainRL column 2', font='boldLabelFont')
  mc.text(label='')
  mc.text(label='text row 1')
  mc.button(label='button', width=mainRLWidth[1]*0.95, height=70)

  mc.setParent(mainCL) # set UI pointer back under the main columnLayout
  mc.text(label='')
  mc.button(label='full window width button', width=winWidth, height=40)

  mc.showWindow(winName)
  mc.window(winName, e=True, width=winWidth, height=1)
  return
buildUI()

我希望这改变了你对Maya的UI系统集的看法。它仍然有很多事情要做。

最重要的是,Maya将尽可能地在其版本中继续支持这些命令,并且它在Windows,MacOS和Linux上的外观和行为仍然相似。