Pergunta

Eu desenvolver ferramentas em Autodesk Maya. Muitas das ferramentas que constroem têm GUIs janelas simples para os animadores e modeladores de usar. Essas interfaces gráficas contêm muitas vezes o que você normalmente esperaria ver em qualquer janela básica; rótulos, tabelas, menus, botões, campos de texto, etc. No entanto, existem limitações para a complexidade das interfaces de usuário que você pode construir com as ferramentas disponíveis, especificamente nos tipos de widgets disponíveis.

Estou interessado em usar algum do wxPython mais avançado widgets, como o ListView (grade), árvore, etc. Isso envolveria usando um completo wxFrame (janela) para exibir toda a interface do usuário, o que essencialmente significa que a janela não seria mais ligada a Maya. Não ofertas infrator, mas isso significa que quando Maya é minimizada, a janela não vai seguir o exemplo.

Eu tentei algo como isto antes com tkinter como um teste, mas descobriu que ele precisava de um MainLoop para ser executado em seu próprio segmento. Isso é lógico, mas no meu caso, ele entra em conflito com o próprio fio de Maya, fazendo essencialmente Maya jeito até que a janela é fechada. Isto é devido ao fato de que Maya é executado todos os scripts, sejam eles MEL ou Python, em um único segmento que as principais ações Maya GUI. Isso é para evitar um script a partir de, por exemplo, excluir um objeto enquanto outro script está tentando fazer um trabalho sobre o mesmo objeto.

wxPython tem essa mesma methodolgy "mainloop". Eu estou querendo saber se há alguma maneira de contornar isso para que ele possa trabalhar dentro de Maya?

Foi útil?

Solução

Eu não tenho certeza se isso é pertinente, mas algumas voltas googling-se que PyQt está dentro de muito popular de Maya. Você poderia tentar a técnica aqui ou aqui (explicado aqui com código fonte) de criar um novo threadloop via Maya e execução dentro desse. Parece Maya tem um módulo incluído que configura um novo objeto de linha, com um QApplication dentro dele:

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

e em seguida, define-se uma função para processar os eventos do Qt:

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

Você provavelmente pode fazer algo semelhante com wxPython também. (Utils.executeDeferred é uma função Maya.) Certifique-se de verificar como criar um non-blocking GUI no wiki wxPython. Em vez de processEvents (), você vai querer configurar um ciclo de eventos e verificação para eventos "pendente" no interior do (espero renomeado?) Função pumpQt acima. (A fonte wxPython tem um Python implementação de MainLoop.) Provavelmente isso deve ser feito através da função app.Yield (), mas eu não tenho certeza.

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()

O wxPython docs indicam SafeYield () é preferido . Novamente, isso parece que poderia ser um primeiro passo, mas eu não tenho certeza que ele vai trabalhar e não apenas travar horrivelmente. (Há alguma discussão sobre o que você quer fazer na wxPython lista de discussão mas é de algumas versões menores de wx atrás.) Há também alguma indicação em vários fóruns que essa técnica causa problemas com a entrada do teclado. Você também pode tentar fazer:

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

para lidar com a atual lista de eventos.

Boa sorte!

Outras dicas

Eu não sei se há uma maneira em torno de um mainloop para o gui, uma vez que é necessário para lidar com todas as cadeias de eventos e redesenhar filas.

Mas há vários meios de comunicação inter-processo, como tubos ou semáforos. Talvez seja uma opção para dividir a sua extensão Maya para o plugin real, sendo apertado em maya, e um aplicativo separado para o gui. Estes dois poderiam usar esses meios para comunicar e informações do modelo de intercâmbio entre plugin e gui. Eu não tenho certeza, no entanto, se eu posso realmente recomendo esta abordagem, porque muito complica a aplicação.

Você poderia ter um olhar para IPython, um Python shell interativo, cuja equipe dev tem colocar algum esforço para integrá-lo com wxPython. Eles têm alguma forma de interromper o ciclo de eventos e ligando para ela, para fazer o seu próprio material.

A melhor maneira de ir é a criação de um QWidget com o que você precisa, e usá-lo de dentro de um MPxCommand através da API C ++. Dessa forma, você também tem a chance de injetar editores personalizados completos para Maya via scriptedPanels.

Mas se você é obrigado a Python, PyQt é o caminho a percorrer.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top