okay here "simple" examples about why I have to define callbacks as strings instead of code.
In XSI, one of the GUI objects that you can create is called a "custom property". A custom property is basically a floating window in which there are widgets. Custom properties can define a layout or not. Custom properties that do not define a layout display a bunch of simple widgets (text fields, sliders for scalar values, checkboxes, etc), vertically on top of each other. Custom properties that define a layout offer a lot more interesting widgets: buttons, tabs, combo boxes, radio buttons, labels, groups, etc. To interactive widgets, callbacks can be attached. So when a button is clicked or a combo box changed, code can be ran. There are two implementations for custom property layouts. 1- property plugins: the entire property is defined in a plugin file. Here the programmer can put any amount of widgets and callbacks he wants. However, the number of such items is constant, one cannot dynamically add or remove elements from a property created in that fashion. (well, perhaps it is possible, but I don't know how). When the XSI application starts, the plugin is loaded. In scripts, the property can be instantiated and inspected. The great benefit of this approach is that the property's layout and logic are persistable. Since those are defined in a plugin, if the plugin is always found, then the property will keep its layout and logic, even if the document is closed and reopen. Here is an example of such a plugin: # Load plugin in XSI def XSILoadPlugin( in_reg ): in_reg.Author = "Bernard Lebel" in_reg.Name = "plugindemo" in_reg.Major = 1 in_reg.Minor = 1 in_reg.RegisterProperty( "propertyplugindemo" ) return True # Define property def propertyplugindemo_Define( io_Context ): """ Add parameters """ oProp = io_Context.source oProp.addparameter3( 'myparameter', 8, '' ) def propertyplugindemo_DefineLayout( io_Context ): """ Skip layout creation. We'll do it at inspection time. """ pass def propertyplugindemo_OnInit(): """ Called when the property is inspected (brought up to the screen for the user to use it) """ oProp = PPG.Inspected(0) # Create property layout oLayout = PPG.PPGLayout oLayout.Clear() oLayout.additem( 'myparameter', 'myparameter' ) # add "myparameter text field" oLayout.addbutton( 'myButton' ) # add "myButton" button PPG.Refresh() # Callbacks for widgets def propertyplugindemo_myButton_OnClicked(): print 'hello world' 2- on-the-fly logic: instead of creating a plugin, the programmer can create a custom property along with layout and logic entirely at execution time. While this prevents the property layout and logic from being persisted, it allows the programmer to define dynamically how many widgets and callback he wants. The problem with this approach is that it I believe it was not designed with Python in mind, but rather JScript. The callbacks defined in "on-the-fly" context, for some reason, must be written as strings and then injected into the property's logic. JScript has the toString() method, which converts easily code blocks into strings. The following Pythoin code works well. Functions are written directly as strings, so no problem. It does exactly the same property as the example above, except that it is being done "on-the-fly" instead of through a plugin. # Instantiate the Applicaiton object, # for running command in the host application xsi = Application # Define callback functions sOnInit = """def OnInit(): pass""" sMyButtonOnClicked = """def myButton_OnClicked(): print 'hello world'""" # Create plain custom property oProperty = xsi.activesceneroot.addproperty( 'CustomProperty', False ) # Add parameters oParameter = oProperty.addparameter3( 'myparameter', 8, '' ) # Get property layout oLayout = oProperty.PPGLayout oLayout.Clear() # Set the layout environment oLayout.Language = 'Python' # Inject logic into the layout. # Join all functions defined in strings. oLayout.Logic = '\n'.join( [sOnInit, sMyButtonOnClicked] ) # Create buttons oLayout.additem( oParameter.scriptname, oParameter.scriptname ) oLayout.addbutton( 'myButton' ) # Inspect the property xsi.inspectobj( oProperty ) Now back to the actual problem. In the task I'm currently having, I have to dynamically create a certain number of layout elements along its logic. The number of elements to create changes from one execution to the next, as it is driven by the user input. Since properpty plugins do not support such dynamic creation, my only solution is with the "on-the-fly" approach. Now what I'd like to do is to create "real" functions, not strings, and convert them into strings for logic injection. Thanks! Bernard _______________________________________________ Tutor maillist - Tutor@python.org http://mail.python.org/mailman/listinfo/tutor