Окно Maya, добавляющее строку динамически с python - PullRequest
0 голосов
/ 05 января 2019

Я работаю над этим некоторое время и не могу найти никакой информации о добавлении строки в окно. Я видел, что это сделано с pyside2 и qt, ведьма будет работать, но пользователи используют несколько версий Maya (2016 = pyside, 2017 = pyside2).

Я хочу добавить виджет в pyside. Я сделал это, когда добавление строки является функцией, такой как добавление строки 1, добавление строки 2 и добавление строки 3, но сценарий становится длинным. Мне нужно родительский rowColumnLayout и сделать это уникальным, чтобы удалить его позже. Также я должен запросить текстовое поле в каждой строке. Может быть, цикл for, который добавляет число в строку? Я действительно не знаю, но вот что у меня есть:

screenshot of widget

from maya import cmds

def row(  ):
    global fed
    global info
    item=cmds.optionMenu(mygroup, q=True, sl=True)
    if item == 1:
        cam=cmds.optionMenu(mygroup, q=True, v=True)
        fed=cmds.rowColumnLayout(nc = 1)
        cmds.rowLayout(nc=7)
        cmds.text(l= cam )
        cmds.text(l=u'Frame Range  ')
        start = cmds.textField('textField3')
        cmds.text(l=u' to ')
        finish = cmds.textField('textField2')
        cmds.button(l=u'render',c='renderTedd()')
        cmds.button(l=u'delete',c='deleteRow()')
        cmds.setParent (fed)
        def deleteRow ():
                cmds.deleteUI(fed, layout=True)
    if item == 2:
        print item
        global red
        cam1=cmds.optionMenu(mygroup, q=True, v=True)
        red = cmds.rowColumnLayout()
        cmds.rowLayout(nc=7)
        cmds.text(l= cam1 )
        cmds.text(l=u'Frame Range  ')
        start = cmds.textField('textField3')
        cmds.text(l=u' to ')
        finish = cmds.textField('textField2')
        cmds.button(l=u'render',c='renderTedd()')
        cmds.button(l=u'delete',c='deleteRow2()')
        cmds.setParent (red)
def deleteRow2 ():
    cmds.deleteUI(red, control=True)
def cameraInfo():
    info=cmds.optionMenu(mygroup, q=True, sl=True)
    print info
def deleteRow ():
    cmds.deleteUI(fed, control=True)
def getCamera():
    layers=pm.ls(type="renderLayer")
    for layer in layers:
        pm.editRenderLayerGlobals(currentRenderLayer=layer)
        cameras=pm.ls(type='camera')
        for cam in cameras:
            if pm.getAttr(str(cam) + ".renderable"):
                relatives=pm.listRelatives(cam, parent=1)
                cam=relatives[0]
                cmds.menuItem(p=mygroup,label=str (cam) )
window = cmds.window()
cmds.rowColumnLayout(nr=10)
mygroup = cmds.optionMenu( label='Colors', changeCommand='cameraInfo()' )
getCamera()
cmds.button(l=u'create camera',aop=1,c='row ()')
cmds.showWindow( window )

1 Ответ

0 голосов
/ 08 января 2019

Это полностью выполнимо с cmds. Хитрость заключается в том, чтобы просто структурировать код так, чтобы кнопки в каждой строке знали и могли работать с виджетами в этой строке; как только это сработает, вы можете добавлять строки весь день.

Чтобы все заработало, нужно сделать две вещи:

  1. Не использовать строковую форму обратных вызовов. Это никогда не является хорошей идеей, по причинам, подробно изложенным здесь
  2. Do используйте замыкания , чтобы убедиться, что ваши обратные вызовы ссылаются на правильные виджеты. Если все сделано правильно, вы можете делать все, что хотите, без лишних затрат.

По сути, это сводится к созданию функции, которая генерирует элементы gui для строки, а также генерирует функции обратного вызова - функция создателя будет «запоминать» виджеты, а создаваемые обратные вызовы будут иметь доступ к виджетам. Вот минимальный пример:

def row_test():

    window = cmds.window(title='lotsa rows')
    column = cmds.columnLayout()

    def add_row(cameraname) :
        cmds.setParent(column)
        this_row = cmds.rowLayout(nc=6, cw6 = (72, 72, 72, 72, 48, 48) )
        cmds.text(l= cameraname )
        cmds.text(l=u'Frame Range')
        start = cmds.intField()
        finish = cmds.intField()

        # note: buttons always fire a useless
        # argument; the _ here just ignores
        # that in both of these callback functions
        def do_delete(_):
            cmds.deleteUI(this_row)

        def do_render(_):
            startframe = cmds.intField(start, q=True, v=True)
            endframe = cmds.intField(finish, q=True, v=True)
            print "rendering ", cameraname, "frames", startframe, endframe

        cmds.button(l=u'render',c=do_render)
        cmds.button(l=u'delete',c=do_delete)

    for cam in cmds.ls(type='camera'):
        add_row(cam)


    cmds.showWindow(window)


row_test()

Определяя функции обратного вызова внутри add_row(), они получают доступ к виджетам, которые хранятся как start и finish. Даже если start и finish будут создаваться снова и снова при каждом запуске функции, значения, которые они хранят, фиксируются замыканиями и по-прежнему доступны при нажатии кнопки. Они также наследуют значение cameraname, поэтому скрипт рендеринга также может получить эту информацию.

С риском для саморекламы: если вам нужно серьезно работать с графическим интерфейсом с использованием cmds, вы должны проверить mGui - модуль python, который делает работу с cmds gui менее сложной для сложных проектов.

...