Попытка динамически заполнить окно в Maya, используя отдельные файлы py для создания модулей. - PullRequest
0 голосов
/ 16 мая 2018

Итак, я пытаюсь построить окно в Maya, в котором будет содержимое, которое будет динамически заполняться.Моя папка имеет следующую структуру: / scripts / modularMenu / <- которая содержит: </p>

init .py

modMenu.py

и /modules / folder

в папке модулей у меня есть: modList.py

mod1.py

mod2.py

mod3.py и т. д. и т. д. и т. д.

В modMenu.py я приказываю Maya рисовать окно, но также запускаю функцию, которая заполняет его на основе содержимого папки модулей, с целью создания новых модулей, которые, если помечены правильно,заполняется в окне.

import maya.cmds as cmds
import sys, os.path
from functools import partial
import modules.modList as mList

def modMenu():
    if (cmds.window('modMenu', exists=True)):
        cmds.deleteUI('modMenu')
    else:
        window = cmds.window( 'modMenu', title="Mod Menu v1.1", iconName='mRig', widthHeight=(400, 800))
        cmds.scrollLayout(width=400, cr=True)
        cmds.columnLayout(adj=True )
        #This all needs to be generated Dynamically.  
        mList.populateWindow()      
        cmds.showWindow( window )

В modList.py у меня есть список категорий и функция для заполнения окна.

typeList = ['Type One', 'Type Two', Type Three']

def populateWindow():
    for type in typeList:
        cmds.frameLayout(label = type, collapsable = True, borderStyle = 'etchedIn')
        cmds.text(label = type, al = 'center', height = 15)
        #Need to then go through each module and import the rest of the form here, each form will have to have a tag to determine if it
        #needs to go in this Category or not.  Perhaps the equivalent of...
        #for each mod.py in /modules folder if their tag == type then add
        cmds.setParent( '..' )

Что я пытаюсь выяснить в следующемОдин из них - как безопасно импортировать содержимое каждого отдельного файла mod1.py, mod2.py и т. д. в этот файл modList.py, а два - как пометить каждый отдельный файл mod.py, чтобы он правильно размещался в системе меню.В идеале я хотел бы включить одну идентичную функцию в каждый файл mod.py и строку, исправляющую ее теги, которую я мог бы вызвать в файле modList.py, но я не уверен, как правильно импортировать из этих файлов мод enмасса, чтобы успешно вызвать эту функцию.Любая помощь будет приветствоваться.

Ответы [ 2 ]

0 голосов
/ 17 мая 2018

На одном уровне это довольно просто. Вы всегда можете добавить элементы gui в макет Maya, если у вас есть строковая ссылка на него, используя команду setParent(), чтобы сообщить Maya, куда направляется новый материал.

В таком случае вам просто нужно передать общий макет в набор функций - не имеет значения, откуда они берутся - и пусть каждая из них вызывает 'setParent`, чтобы сделать макет активным и добавить к этому. Вот пример того, как это будет происходить, используя отдельные функции вместо отдельных модулей - это не будет иметь значения, если эти разные функции имеют разное происхождение модуля.

def button_section(parent):
    cmds.columnLayout(adj=True)
    cmds.frameLayout(label='buttons') 
    cmds.columnLayout(adj=True)
    cmds.rowLayout(nc=2, cw = (200,200))
    cmds.button(label = 'red', backgroundColor=(1,0.5,0.5), width=100)
    cmds.button(label = 'blue', backgroundColor =(0.5, 0.5, 1), width=100)

def text_section(parent):
    cmds.separator()
    cmds.text(label = 'time:')
    cmds.text(label = 'It is currently ' + str(datetime.datetime.now()))
    cmds.text(label = 'main layout is ' + parent)
    cmds.separator()

def object_section(parent):
    cmds.columnLayout(adj=True)
    cmds.frameLayout(label = 'scene')
    cmds.columnLayout(adj=True, rs = 12, columnAttach = ('both', 8) )
    for object in cmds.ls(type='transform'):
        select_the_thing = lambda b: cmds.select(object)
        cmds.button(label = object, c = select_the_thing)   

def create_window(*sections):
    window = cmds.window(title = 'example')
    main_layout = cmds.columnLayout(adj=True)
    for each_section in sections:
        cmds.setParent(main_layout)
        each_section(main_layout)
    cmds.setParent(main_layout)
    cmds.columnLayout(adj=1, columnAttach = ('both', 8))
    cmds.separator()
    cmds.text(label = 'here is a footer')
    cmds.showWindow(window)

create_window(button_section, text_section, object_section)

Если вы не знакомы с синтаксисом, функция create_window с * принимает любое количество аргументов. В этом случае он просто берет три отдельные функции секции. Вы можете, однако, написать его, чтобы просто взять список функций. В любом случае логика одинакова - просто setParent вернитесь к основному макету, и вы сможете добавлять новые элементы в макет.

В этом примере я передал имя основного макета в каждую из различных функций макета. Это полезно, так что вы можете сделать такие вещи, как получить ширину элемента макета, который владеет вами, или рекурсивно подняться на более высокий уровень.


В общем, здесь вы должны следить за тем, чтобы спроектировать это так, чтобы разные секции действительно были независимы друг от друга. Ситуация быстро усложняется, если кнопка в разделе A должна знать состояние флажка в разделе B. Однако это показывает вам основы того, как составлять макеты в Maya.

Я бы очень осторожно попытался заполнить меню на основе содержимого папки вашего модуля - если вы удалите модуль, но не забудете удалить созданный им pyc-файл, вы можете в итоге с фантомным разделом пользовательского интерфейса, который вы не ожидаете. Было бы лучше просто организовать код как обычные модули, а затем создать простой скрипт, который явно запрашивал бы модули. Тогда вы сможете точно знать, чего ожидать при локальной установке.

0 голосов
/ 16 мая 2018

1 - вам придется использовать exec () или «import mod, mod.doIt ()», но то, что «безопасно», будет зависеть от ваших проверок

2 - Я не уверен, что понял. Хотите изменить порядок мод по номеру? если нет, я предположил, что вы можете сделать JSON для хранения заказа или, возможно, сохранить некоторые метаданные

...