maya
Создание пользовательского интерфейса Maya
Поиск…
параметры
| параметр | подробности |
|---|---|
| e / edit | говорит Майя, что вы хотите изменить стоимость существующего имущества |
| q / query | говорит Майя, что вы хотите получить стоимость существующего имущества |
замечания
Майя поставляется с довольно полным набором инструментов пользовательского интерфейса, который включает в себя окна, макеты и различные элементы управления. Это реализовано с использованием платформы QT на C ++, но доступно пользователям MEL и Python с помощью набора команд Maya по умолчанию.
QT
Продвинутые пользователи могут расширить интерфейс Maya с помощью C ++ или Python. Майя версии с 2012 по 2016 год используют Pyside и QT4; Майя 2017 использует Pyside2 и QT5. Подробнее здесь
Примечание. Старая ссылка в Интернете относится к инструментарию майя GUI как «ELF»; это по-прежнему правильное имя, но оно редко используется.
Пример базового интерфейса пользователя [Python]
Инструментарий GUI Maya создает множество элементов пользовательского интерфейса в простой, императивной форме. Существуют базовые команды для создания и редактирования виджета графического интерфейса; виджеты идентифицируются уникальным именем строки.
Все команды gui имеют одинаковую базовую форму: вы указываете тип команды и имя строки объекта, над которым хотите работать или создаете, вместе с флагами, определяющими внешний вид или поведение виджета. Так, например, чтобы создать кнопку, которую вы используете:
cmds.button('my_button', label = 'my label')
Это создаст новую кнопку gui. Чтобы отредактировать кнопку, вы должны использовать ту же команду с флагом edit (короткая версия - это просто e ). Таким образом, вы можете изменить ярлык кнопки следующим образом:
cmds.button('my_button', e=True, label = 'a different label')
и вы можете запросить текущее значение свойства с помощью query или флага q :
cmds.button(`my button`, q=True, label=True)
# 'a different label'
Именование имен виджетов
Когда вы создаете новый виджет с помощью команды UI, вы можете указать имя, которое хотите получить новому виджету. Тем не менее, это не гарантируется: Maya предоставит кнопке имя, которое вы просили, - если вы дали ему символ, который он не распознает, или если у вас уже есть виджет с тем же именем, вы можете получить другое имя. Всегда хорошая практика захватить имя нового виджета, когда оно создано, чтобы избежать сюрпризов:
my_button = cmds.button('my_button')
cmds.button(my_button, e=True, label = "a new label")
Функции обратного вызова
Многие виджеты включают события, которые могут запускать функции обратного вызова, когда пользователь взаимодействует с виджетами. Например, когда нажата кнопка, установлен флажок или выбран выпадающий список, вы можете запустить функцию.
Точный флаг, связанный с этим событием, зависит от виджета, но типичный обратный вызов будет выглядеть так:
def callback_fn(_ignore):
print "button pressed"
button = cmds.button(label='press me', command = callback_fn)
Нажатие кнопки будет печатать кнопку «нажата» в окне слушателя. Большинство виджета загораются некоторыми аргументами, когда активируются их обратные вызовы - например, button всегда включает в себя логическое значение, поэтому вам нужно убедиться, что обработчик обратного вызова имеет правильную подпись, чтобы идти с виджемом, который вы используете. Вот почему callback_fn() принимает аргумент, даже если он ему не нужен.
Назначение обратного вызова
Maya поддерживает два разных способа подключения функций обратного вызова:
# this works, but is not a great idea
cmds.button(label = 'string reference', command = 'string_name_of_function')
# use this form whenever possible
cmds.button(label = 'direct function reference', command = callback_fn)
В первом примере обратный вызов назначается строковым значением. Майя найдет обратный вызов в глобальной области Python, которой обычно трудно получить при написании правильно организованного кода. Обратные вызовы с именами строк также медленнее. Второй пример передает действительную функцию Python для обратного вызова - эта форма предпочтительнее, поскольку она выполняется быстрее, и если вы не смогли предоставить действительную функцию функции обратного вызова, вы узнаете, когда создается пользовательский интерфейс, а не когда виджеты пользовательского интерфейса фактически используются.
Если вы хотите передать значение аргумента функции обратного вызова, вы можете использовать аргументы лямбда , замыкания или functools.partial для обратного вызова.
Использование partial :
from functools import partial
....
def callback_fn(myValue, _ignore): # _ignore swallows the original button argument
print myValue
button = cmds.button(label='press me', command = partial(callback_fn, "fooo"))
Использование lambda :
def callback_fn(myValue):
print myValue
button = cmds.button(label='press me', command = lambda _ignore: callback_fn("fooo"))
# here the lambda needs to handle the button argument
Использование закрытий
b = cmds.button(label = 'press me')
# by defining this function when `b` exists, we can use it later
# without storing it explicitly
def get_button_label(*_):
print "label of button", b, " is ", cmds.button(b, q=True, l=True)
cmds.button(b, e=True, c=get_button_label)
Там больше о именах обратных вызовов строк и функции обратного вызова здесь
Создание окна
# create a window with a button that closes the window when clicked
window = cmds.window(title='example window') # create the window
layout = cmds.columnLayout(adjustableColumn=True) # add a vertical layout
def close_window(*_):
cmds.deleteUI(window) # deletes the window above
button = cmds.button(label= 'press to close", command = close_window)
# show the window
cmds.showWindow(window)
Лямбда и петли
Lambdas - полезный ярлык для подключения к элементам GUI.
b = cmds.button("make a cube", command = lambda _: cmds.polyCube())
Однако из-за того, как Python захватывает переменные внутри lambdas, вы можете получить неожиданные результаты, если вы связываете команды с использованием lambdas внутри цикла. Например, похоже, что он должен создавать кнопки, которые создают сферы разных размеров:
# warning: doesn't work like it looks!
for n in range(5):
b = cmds.button("sphere size %i" % n, command = lambda _: cmds.polySphere(radius=n))
Кнопки будут помечены правильно, но все они будут использовать один и тот же радиус (4), потому что lambdas все захватят это значение, когда цикл закроется. TLDR: если вы генерируете обратные вызовы внутри цикла, используйте functools.partial или другой метод для захвата значений - lambdas не работают для этого приложения. Подробнее см. Здесь