KB no longer maintained - Voxler is a retired product. Golden Software retired products are still supported, but no longer receive new features or updates. Many of Voxler's features are moving to Surfer . Please contact support@goldensoftware.com with any questions. |
This article contains a sample Python script that is helpful to run if you are scripting in Python; it handles error handling and wraps Voxler's automation model to look like a standard automated application.
To run this script, copy the script below, or click here to download the PY file: Voxler.py.
*********
"""This is a helper module so that users of Voxler automation can talk to Voxler with some built in ease of use functions.""" import traceback import win32com.client import os class ApiError(Exception): def __init__(self, msg): super(ApiError, self).__init__() self.msg = msg def __str__(self): return repr(self.msg) class Command(object): """This encapsulates the error checking and ensures that exceptions are thrown on failure.""" def __init__(self, api, cmd): self.api = api self.cmd = cmd # Catch all exceptions, get all bad return codes. cmd_constructed = False try: cmd_constructed = self.api.Construct(self.cmd) except: pass if not cmd_constructed: raise ApiError("Failed to construct command '{0}'".format(self.cmd)) def option(self, key, value): opt_valid = False try: opt_valid = self.api.Option(key, value) except: pass if not opt_valid: raise ApiError("Failed to set option '{0}':'{1}'".format(key, value)) def do(self): done = False try: done = self.api.Do() except: pass if not done: raise ApiError("Failed to execute command '{0}'".format(self.cmd)) def doOnce(self): done = False try: done = self.api.DoOnce() except: pass if not done: raise ApiError("Failed to execute command '{0}'".format(self.cmd)) class Voxler: """Wraps Voxler's automation to look like any other automated application. Turns this: api.Construct("CreateModule") api.Option("Type", "Axes") api.Option("AutoConnect", "True") api.Option("SourceModule", "ScatterPlot") api.Do() Into a more consistent, pythonic call: voxler.command('CreateModule', {'Type':'Axes', 'AutoConnect':'True', 'SourceModule':'ScatterPlot'}) And Even: voxler.About() voxler.Open(Path=voxler.path()+"Samples\\Gold (ScatterPlot).voxb") ... """ def __init__(self): """Attaches to or creates an instance of Voxler, makes it visible.""" try: self.app = win32com.client.GetObject(Class="Voxler.Application") except: self.app = win32com.client.Dispatch("Voxler.Application") self.app.Visible = 1 self.api = self.app.CommandApi cmd = Command(self.api, "New") cmd.do() def command(self, cmd_name, opts): """ Executes a single command, and sets all of the options. Example: # Creates an Axes module that connects to the ScatterPlot voxler.command('CreateModule', {'Type':'Axes', 'AutoConnect':'True', 'SourceModule':'ScatterPlot'}) """ cmd = Command(self.api, cmd_name) for k, v in opts.items(): cmd.option(k, v) cmd.do() def commandOnce(self, cmd_name, opts): """ Executes a single command, and sets all of the options. Example: # Creates an Axes module that connects to the ScatterPlot voxler.command('CreateModule', {'Type':'Axes', 'AutoConnect':'True', 'SourceModule':'ScatterPlot'}) """ cmd = Command(self.api, cmd_name) for k, v in opts.items(): cmd.option(k, v) cmd.doOnce() def command_sequence(self, cmd_name, opts, opts_seq): """Executes a command + opts, once for every option in opts_seq. Note: the options are not set in order. The idea for this function is to set a whole bunch of options for a module or whatever, and not have to keep calling Construct, Option, Do. Example: Modifies the Axes Module, and for each of the key/values in seqOpts executes a new ModifyModule command on the "Axes" module, setting each of the options individually. voxler.command( # This command is created and this option is set "ModifyModule", {"Module":"Axes"}, # For each key/value pair, the above command is executed. { "AxesXAxisShow":"True", "AxesXAxisColor":"light green", "AxesXAxisBeg":"20", "AxesXAxisEnd":"110", "AxesXAxisCross1":"0", "AxesXAxisCross2":"50", "AxesXAxisPlane":"45", "AxesXAxisTitle":"X Axis Title", "AxesXAxisShowLabels":"True", "AxesXAxisFlipLabelsX":"True", "AxesXAxisFlipLabelsY":"True" } ) """ for cmdOptKey, cmdOptVal in opts_seq.items(): # Keep things clean and make the command each time. cmd = Command(self.api, cmd_name) # Set the initial options common to all commands in this sequence. for k, v in opts.items(): cmd.option(k, v) # Set the option for this key/value pair. cmd.option(cmdOptKey, cmdOptVal) cmd.do() def quit(self): """Quits Voxler, obviously.""" self.app.Quit() # Special property-like methods. def path(self): """Returns the path that Voxler is running from. Useful for loading files.""" return self.app.Path def samplePath(self): """Returns the path that Voxler can load samples from.""" path = os.environ.get('GSSRC') if path is not None: path = path + "\\Voxler\\Setup\\ProgFiles\\Samples" else: path = self.path() + "\\Samples" return path def name(self): return self.app.Name def fullname(self): return self.app.FullName def version(self): return self.app.Version def __getattr__(self, attrib, **kwargs): """This function is called when nothing else matches a member for a Voxler object. It tries to take the passed in attribute and make a command out of it. Examples: 1. voxler.About() Actually runs the behind the scenes: api.Construct("About") api.Do() 2. voxler.Open(Path=voxler.path()+"Samples\\Gold (ScatterPlot).voxb") Creates an Open command, sets it the Path option, then calls Do on it. api.Construct("Open") api.Option("Path", ""Samples\\Gold (ScatterPlot).voxb") api.Do() """ # Don't intercept the default Python class attributes. if attrib.startswith("__") and attrib.endswith("__"): return self.__dict__[attrib] cmd = Command(self.api, attrib) # This returns a function that accepts keyword arguments and then # runs the command in the closure. def wrapper(**kwargs): for k, v in kwargs.items(): cmd.option(k, v) cmd.do() return wrapper # If this is run by itself, then run it as a test. if __name__ == '__main__': voxler = None try: voxler = Voxler() # Launches the About, as expected. if False: voxler.About() voxler.Open(Path=voxler.path()+"Samples\\Gold (ScatterPlot).voxb") # Fails, like it should. if False: voxler.NotReallyACommand() # Throws from Voxler. Like it is supposed to. if False: voxler.command('Not A Command', {'Type':'Axes', 'AutoConnect':'True', 'SourceModule':'ScatterPlot'}) # Errors like it is supposed to. if False: voxler.command( "ModifyModule", { "Module":"Axes", "NonExistentOption":"Does it matter?"}) except: print "Unexpected error:" traceback.print_exc() finally: if voxler is not None: voxler.quit() del voxler
Updated July 9, 2018
Comments
0 comments
Please sign in to leave a comment.