Использование внешних библиотек GUI для создания пользовательских интерфейсов в Autodesk Maya

Я разрабатываю инструменты в Autodesk Maya. Многие из инструментов, которые я создаю, имеют простые оконные GUIs для аниматоров и модельеров. Эти GUI часто содержат то, что вы обычно ожидаете увидеть в любом основном окне: метки, списки, меню, кнопки, текстовые поля и т. д. Однако существуют ограничения на сложность UIs, которые можно построить с помощью доступных инструментов, особенно в типах доступных виджетов.

Мне интересно использовать некоторые из более продвинутых wxPython виджеты, такие как элемент управления ListView (сетка), дерево, и т. д. Это включало бы использование полного wxFrame (window) для отображения всего пользовательского интерфейса, что по существу означало бы, что окно больше не будет привязано к Maya. Не нарушитель сделки, но это означает, что когда Майя свернута, окно не будет следовать примеру.

Я пробовал что-то подобное раньше с tkinter в качестве теста, но обнаружил, что ему нужен MainLoop для запуска в своем собственном потоке. Это логично, но в моем случае это противоречит Майе нить, по существу заставляющая Майю висеть, пока окно не закроется. Это связано с тем, что Maya запускает все скрипты, будь то MEL или Python, в одном потоке, который разделяет основной GUI Maya. Это делается для того, чтобы один скрипт не удалял объект, в то время как другой пытается работать с тем же объектом.

wxPython имеет ту же методику" mainloop". Мне интересно, есть ли способ обойти это, чтобы он мог работать внутри Майи?

3 ответов


Я не уверен, что это уместно, но некоторые гуглят, что PyQt довольно популярен внутри Майи. Вы можете попробовать технику здесь или здесь (см. здесь с исходным кодом) создания нового threadloop через Maya и выполнения внутри этого. Кажется, у Maya есть модуль, который устанавливает новый объект thread с QApplication внутри него:

def initializePumpThread():
    global pumpedThread
    global app
    if pumpedThread == None:
        app = QtGui.QApplication(sys.argv)
        pumpedThread = threading.Thread(target = pumpQt, args = ())
        pumpedThread.start()

и затем устанавливает функцию для обработки Qt события:

def pumpQt():
    global app
    def processor():
        app.processEvents()
    while 1:
        time.sleep(0.01)
        utils.executeDeferred( processor )

вы, вероятно, можете сделать что-то подобное с wxPython. (а utils.executeDeferred является функцией Maya.) Не забудьте проверить, как создать неблокирующий GUI на вики wxPython. Вместо processEvents () вы захотите настроить цикл событий и проверить "ожидающие" события внутри (надеюсь, переименованы?) функция pumpQt выше. (Источник wxPython имеет реализация Python в MainLoop.) Вероятно, это должно быть сделано через приложение.Функция Yield (), но я не уверен.

def pumpWx():
    global app
    def processor():
        app.Yield(True)
    while 1:
        time.sleep(0.01)
        utils.executeDeferred( processor )

def initializePumpThread():
    global pumpedThread
    global app
    if pumpedThread == None:
        app = wx.App(False)
        pumpedThread = threading.Thread(target = pumpWx, args = ())
        pumpedThread.start()

в wxPython, в документах укажите SafeYield () предпочтительнее. Опять же, это может быть первым шагом, но я не уверен, что это сработает, а не просто ужасно рухнет. (Есть некоторые дискуссии о том, что вы хотите сделать на wxPython, в список рассылки но это из нескольких второстепенных версий wx назад.) Есть также некоторые указания на различных форумах, что этот метод вызывает проблемы с ввод с клавиатуры. Вы также можете попробовать сделать:

def processor():
  while app.Pending(): app.Dispatch()

для работы с текущим списком событий.

удачи!


Я не знаю, есть ли способ обойти mainloop для gui, так как он необходим для обработки всех цепочек событий и перерисовки очередей.

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

вы можете взглянуть на IPython, интерактивную оболочку Python, команда разработчиков которой приложила некоторые усилия для интеграции с wxPython. У них есть какой-то способ прервать цикл событий и подключиться к нему, чтобы делать свои собственные вещи.


лучший способ - создать QWidget с тем, что вам нужно, и использовать его из MPxCommand через API c++. Таким образом, у вас также есть возможность ввести полные пользовательские Редакторы в Maya через scriptedPanels.

но если вы привязаны к Python, pyQt-это путь.