Wednesday, March 16, 2011

Maya wxWindow

This a a template to create interactive wxWindows in Maya. The same UI can be ported to most applications using a python interpreter by only changing the makeCube method. However, not all software and/or versions fully support wxWidgets. The key difference you'll want to remember between a standard window and one from Maya is to omit initializing wx.app.MainLoop().
import wx
import maya.cmds as cmds

def getApp(kill = None):
 if kill:
  if MyFrame.instance:
   MyFrame.instance.Hide()
   MyFrame.instance.Destroy()
   MyFrame.instance = None
 else:
  if MyFrame.instance:
   MyFrame.instance.Show()
  else:
   MyFrame.create()
 
class MyFrame(wx.Frame):
 instance = None
 
 @classmethod
 def create( cls, *args, **kw ):
  app = wx.GetApp()

  if app is None:
   app = wx.App( redirect = False )
  
  frame = cls( None, app, *args, **kw )
  frame.Show(True)
 
 def __init__(self, parent, app):
  MyFrame.instance = self
  wx.Frame.__init__(self, parent, wx.ID_ANY, "MyFrame", wx.DefaultPosition, wx.Size(500,500), wx.DEFAULT_FRAME_STYLE )
  
  self.panel = wx.Panel(self, -1)
  self.sphereButton = wx.Button(self.panel, -1, "Sphere")
  self.cubeButton = wx.Button(self.panel, -1, "Cube")
   
  self.Bind( wx.EVT_ICONIZE, self.OnMinimize )
  self.Bind( wx.EVT_CLOSE, self.OnClose )
  self.sphereButton.Bind(wx.EVT_BUTTON, self.makeSphere)
  self.cubeButton.Bind(wx.EVT_BUTTON, self.makeCube)
  
  mainSizer = wx.BoxSizer(wx.VERTICAL)
  panelSizer = wx.BoxSizer(wx.HORIZONTAL)
  
  panelSizer.Add(self.sphereButton, 0, 0, 0)
  panelSizer.Add(self.cubeButton, 0, 0, 0)
  self.panel.SetSizer(panelSizer)
  mainSizer.Add(self.panel, 1, wx.EXPAND, 0)
  
  self.SetSizer(mainSizer)
  mainSizer.Fit(self)
  self.Layout()
 
 def makeSphere(self, evt):
  cmds.polySphere()
  
 def makeCube(self, evt):
  cmds.polyCube()
 
 def OnClose(self,event):
  self.Show(False)

 def OnMinimize(self, event):
  self.Show(0);

XSI Plugin

Creating XSI plugins in python is extremely easy. This file will add a new menu and menuItem to the main toolbar. You can actually attach a menuItem to many other XSI widgets besides the main toolbar using the RegisterMenu command. Like most UI elements, they are not initialized until they are called the first time.
import win32com.client
from win32com.client import constants

def XSILoadPlugin( in_reg ):
 in_reg.Author = ""
 in_reg.Name = "myPlugin"
 in_reg.Email = ""
 in_reg.URL = ""
 in_reg.Major = 1
 in_reg.Minor = 0
 print in_reg.Name, "has been loaded."
 
 in_reg.RegisterMenu(constants.siMenuMainTopLevelID,"MenuTitle",0,0)
 in_reg.RegisterCommand("MenuItem","MenuItem") #command, scriptname
 return 1

def XSIUnloadPlugin( in_reg ):
 print in_reg.Name, "has been unloaded."
 return 1

def MenuTitle_Init( in_ctxt ):
 oMenu = in_ctxt.Source
 oMenu.AddCommandItem("MenuItem","MenuItem") #menuname, command
 return 1

def MenuItem_Init( in_ctxt ):
 oCmd = in_ctxt.Source
 oCmd.Description = ""
 oCmd.ReturnValue = 1
 return 1

def MenuItem_Execute(  ):
 print "Command to Run"
 return 1