Automating the hosting application using IronPython
With the code below I could host an Avalon TextBox in my application, type Python expressions and see the results. What I still could not do (when I first finished the code) was execute code back in my application. I needed to give the Python code an object it could make calls on, and I had no examples of doing this. However, this turned out to be incredibly simple. On IronPython's PythonEngine class I noticed a method called SetVariable. It appeared to inject a variable into the Python engine pointing to an object. I copied the code to my PythonProcessor (you've already seen these lines):
public void SetVariable(string name, object val)
{
Ops.SetAttr(this.Module, name, val);
}
Then, I called this method from my application, passing it the root of my object model:
this.consolePane.Processor.SetVariable("ApplicationManager", this.applicationManager);
A few moments later, I executed ApplicationManager.Version from my console, and I was on my way. Unfortunately, the application I am working on isn't public, and the hook I am using never will be. But I can give you a taste of the sort of scripts I can write in Python:
def createRectangle(self, x, y, brush=Brushes.Red):
rect = self.createElement(Rectangle)
undoTransaction = self._viewModel().CreateUndo("CreateRectangle")
try:
self.addElement(rect, "Rect")
rect.Width = 17
rect.Height = 15
rect.SetValue(Shape.FillProperty, brush)
rect.SetValue(Canvas.TopProperty, x)
rect.SetValue(Canvas.LeftProperty, y)
undoTransaction.Commit()
finally:
undoTransaction.Dispose()
return rect
These posts should give anyone interested enough to piece together a way of hosting IronPython in their own app. I'll try to provide a full sample later, but that will have to wait until I have time to write an app, and for newer Avalon bits to go public.