Exploring Altair Inspire APIs: A Python Demo for GUI Development

Karthi Kandasamy
Karthi Kandasamy
Altair Employee
edited September 17 in Altair HyperWorks

Altair Inspire is a powerful tool for simulation-driven design, allowing users to create, modify, and analyze geometries. Through its Python API, developers can extend Inspire’s capabilities and automate tasks. In this blog, we'll explore a few interesting examples using the Inspire API to demonstrate geometry creation, manipulation, and debugging within the environment.

Example 1: Button Group

In this example, we demonstrate how to create a group of buttons where only one can be selected at a time, similar to a group of radio buttons.

 

############################################################################## # Example 1: Button Group  from hwx import gui  # Create some CheckBoxes (could also be used as radio buttons) buttons = [     gui.CheckBox("Red"),      gui.CheckBox("Green"),      gui.CheckBox("Blue") ]  # Make the buttons mutually exclusive by grouping them together # This ensures that only one checkbox can be selected at a time gui.ButtonGroup(buttons)  # Layout the buttons vertically using a VFrame frame = gui.VFrame(buttons)  # Display the frame with the grouped buttons show(frame)  ############################################################################## 

Example 2: Message Dialogs

In this example, we show how to create buttons that display different types of messages when clicked.

############################################################################## # Example 2: Message Dialogs  from hwx import gui  # Function to create a button that shows a message dialog when clicked def button(text, message_function):     return gui.PushButton(text, command=lambda: message_function("Hello World"))  # Function to create a custom message dialog button def customButton():     msg = gui.MessageDialog(         message="Hello World",          icon="redcheck",          button1="Close"     )     return gui.PushButton("With Button", command=lambda: msg.show())  # Create a frame with different types of message buttons frame = gui.HFrame(     button("Information", gui.tellUser),  # Info dialog     button("Warning", gui.warnUser),      # Warning dialog     button("Error", gui.showError),       # Error dialog     button("Success", gui.showSuccess),   # Success dialog     customButton()                        # Custom dialog with icon )  # Display the frame with message buttons show(frame)  ############################################################################## 

Example 3: Cursor Change

This example demonstrates how to dynamically change the cursor icon when a button is clicked.

############################################################################## # Example 3: Cursor Change  from hwx import gui import time  # Function to create a button that changes the cursor when clicked def makeButton(cursor):     def setCursor(event, cursor=cursor):         with gui.waitCursor(cursor):             time.sleep(1)  # Simulate a delay while changing the cursor      return gui.PushButton(cursor, command=setCursor)  # Get a list of all predefined cursor types cursors = sorted(gui.Cursor.predefined.keys())  # Create buttons for each cursor type buttons = [makeButton(cursor) for cursor in cursors]  # Layout the buttons in a grid with 3 rows and spacing of 2 units frame = gui.GridFrame(buttons, nrows=3, spacing=2)  # Display the frame with cursor-changing buttons show(frame)  ############################################################################## 

Example 4: VFrame (Vertical Layout)

This example demonstrates arranging widgets (buttons, labels, checkboxes) vertically using a VFrame.

  • Vertical Layout: We arrange multiple widgets in a vertical layout using VFrame.
  • Stretchable Space: The "<->" symbol is used to add a stretchable space between widgets to adjust layout flexibility.
  • Widgets: We add labels, checkboxes, and a push button inside the frame, and they are arranged vertically.

 

############################################################################## # Example 2: VFrame  from hwx import gui  # Arrange widgets vertically vframe = gui.VFrame(     (gui.Label("A Label"), gui.CheckBox("A CheckBox")),     (gui.Label("B Label"), gui.CheckBox("B CheckBox")),     ("<->", gui.PushButton("A PushButton"))  # Blank stretchable space before the button )  # Run the demo show(vframe)  ############################################################################## 

Example 5: HFrame (Horizontal Layout)

This example demonstrates arranging widgets horizontally using an HFrame and dynamically changing a label’s visibility and enabled state.

############################################################################## # Example 3: HFrame  from hwx import gui  # Define callbacks for visibility and enable state changes def onVisible(event):     label.visible = event.value  def onEnabled(event):     label.enabled = event.value  # Create checkboxes to toggle label visibility and enabled state visible = gui.CheckBox("Visible?", value=True, command=onVisible) enabled = gui.CheckBox("Enabled?", value=True, command=onEnabled) label = gui.Label("A Label")  # Arrange the checkboxes and label horizontally hframe = gui.HFrame(visible, enabled, label)  # Run the demo show(hframe)  ############################################################################## 

Example 6: GridFrame

This example shows how to arrange widgets (labels, buttons, and text input) in a grid layout using GridFrame.

############################################################################## # Example 4: GridFrame  from hwx import gui  # Arrange widgets in a grid grid_frame = gui.GridFrame(     (gui.Label("Label 1"), gui.PushButton("Click me"), gui.LineEdit(1.0)),     (gui.Label("Label 2"), gui.PushButton("Click me"), gui.LineEdit(2.0)),     (gui.Label("Label 3"), gui.PushButton("Click me"), gui.LineEdit(3.0)),     # Additional options for rows, columns, and padding can be added )  # Run the demo show(grid_frame)  ############################################################################## 

 

Example 7: CollapsibleFrame

This example demonstrates how to use a CollapsibleFrame to display widgets inside a collapsible container.

############################################################################## # Example 5: CollapsibleFrame  from hwx import gui  # Create an icon and radio buttons for speed/accuracy options icon = gui.IconLabel(icon=("fdmSpeedAccuracyImageStrip_48.png", (7, 0)), size=(48, 48)) speedAccuracy = gui.VRadioButtons(values=(("faster", "Faster"), ("accurate", "More Accurate")))  # Arrange icon and radio buttons in a horizontal layout layout = gui.HBoxLayout((icon, 40, speedAccuracy))  # Create a collapsible frame to hold the layout frame = gui.CollapsibleFrame(     text="Speed Accuracy Settings",     expanded=False,  # Start in collapsed state     children=(layout) )  # Run the demo show(frame)  ############################################################################## 

Example 8: NoteBook (Tabbed Interface)

This example demonstrates how to use a NoteBook widget to create a tabbed interface.

############################################################################## # Example 1: NoteBook  from hwx import gui  # Callback function when a new tab is selected def tabChanged(event):     notebook = event.widget  # Get the notebook object     label = notebook.TabLabel(notebook.current)  # Get the label of the current tab  # Create a notebook widget and populate it with tabs notebook = gui.NoteBook(flat=False, command=tabChanged)  notebook.addTab(gui.LineEdit("First"), text="First") notebook.addTab(gui.LineEdit("Second"), text="Second") notebook.addTab(gui.LineEdit("Third"), text="Third")  # Display the notebook show(notebook)  ############################################################################## 

Example 9: Dialog (Popup Window)

This example shows how to create a dialog box with editable fields and a close button.

############################################################################## # Example 2: Dialog  from hwx import gui  # Callback function when the 'Close' button is clicked def onClose(event):     gui.tellUser(f'Distance is {distance.value}')     dialog.hide()  # Hide the dialog  distance = gui.DoubleEdit(9.81, units='length')  # Input field for distance height = gui.DoubleEdit(2.91, units='length')    # Input field for height close = gui.Button('Close', command=onClose)     # Button to close the dialog  # Create a dialog box with distance and height inputs and a close button dialog = gui.Dialog(     caption="The distance",     children=(         gui.GridFrame(             ("Distance", 5, distance),             ("Height", 5, height)         ),         5, ("<->", close)     ) )  # Show the dialog show(dialog)  ############################################################################## 

Example 10: DockWindow (Dockable Window)

This example demonstrates a DockWindow that contains multiple icons and action buttons.

############################################################################## # Example 3: DockWindow  from hwx import gui  # Create a dockable window with some icon labels and action buttons window = gui.DockWindow(     caption="Run",     docked=False,     children=gui.HFrame(         gui.Label(icon="dialogBooleanCombineStrip-32.png"),         gui.Label(icon="dialogBooleanIntersectStrip-32.png"),         gui.Label(icon="dialogBooleanSubtractStrip-32.png")     ),     height=145, width=150 )  # Add buttons in the title bar for additional actions window.titleBar.exitButton() window.titleBar.resetButton(command=lambda: gui.tellUser("Reset button clicked.")) window.titleBar.executeCreateandExitButton(command=lambda: gui.tellUser("Create and Exit button clicked.")) window.titleBar.executePlayButton(command=lambda: gui.tellUser("Play button clicked."))  # Display the dockable window window.show()  ############################################################################## 

Example 11: exec (Executing a Dialog)

This example demonstrates creating a dialog with a color picker and executing it to capture the user’s selection.

############################################################################## # Example 4: exec  from hwx import gui  class ColorPicker(gui.Dialog):     def createContents(self):         self.caption = 'Choose Color'         options = gui.ComboBox(['Red', 'Green', 'Blue'])  # Drop-down menu for color options         button = gui.Button('Accept', command=lambda: self.accept(options.value))         gui.VBoxLayout(options, button, parent=self)  # Create and execute the color picker dialog color = ColorPicker().exec() gui.tellUser(f'You chose {color}')  ############################################################################## 

Example 12: ActionDialog

This example showcases how to use ActionDialog, where dialogs are triggered by an action or a button.

############################################################################## # Example 5: ActionDialog  from hwx import gui  class MyActionDialog(gui.ActionDialog):     def createContents(self):         self.caption = 'Dialog Toggled By Action'         gui.HBoxLayout(gui.Table(values=[range(10) for _ in range(10)]), parent=self)         self.layout.resizeMode = 'Auto'  class MyButtonDialog(gui.ActionDialog):     def createContents(self):         self.caption = 'Dialog Toggled By Button'         gui.HBoxLayout(gui.Table(values=[range(10) for _ in range(10)]), parent=self)         self.layout.resizeMode = 'Auto'  # Display action dialog toggled by button show(gui.HFrame(     gui.SpriteActionGroup(children=[         gui.SpriteAction(             text="Action Group",             icon=("ribbonRigidGroupStrip-80.png", (0, 5)),         ),         gui.SpriteAction(             icon=("ribbonSatelliteListStrip-80.png", (3, 5)),             dialog=MyActionDialog,  # Action dialog triggered by an icon         )     ]),     gui.Button(         icon="glyphAutomaticStrip-16.png",         dialog=MyButtonDialog  # Button dialog triggered by a button     ) ))  ############################################################################## 

Example 13: MicroDialog

This example demonstrates the use of a MicroDialog with various interactive buttons for adjusting values.

############################################################################## # Example 6: MicroDialog  from hwx import gui  # Callback functions for the buttons def onYClick(): yField.value = 1; xField.value = zField.value = 0.0 def onZClick(): zField.value = 1; yField.value = xField.value = 0.0 def onXClick(): xField.value = 1; yField.value = zField.value = 0.0 def onActiveClick():     reverse.enabled = not reverse.enabled     gravity.enabled = not gravity.enabled def plusMinusClick():     gravity.value *= -1.0  # Define widgets for the dialog active = gui.PushButton(icon='microEditStrip-18.png', command=onActiveClick) reverse = gui.PushButton(icon='microReverseMagnitudeStrip-18.png', command=plusMinusClick) gravity = gui.DoubleEdit(9810) xField = gui.DoubleEdit(1) yField = gui.DoubleEdit(0) zField = gui.DoubleEdit(0)  # Position buttons positions = (gui.PushButton("POS1", command=lambda: moveToPos(0, 0)),              gui.PushButton("POS2", command=lambda: moveToPos(50, 50)),              gui.PushButton("POS3", command=lambda: moveToPos(100, 0)))  # Create a MicroDialog microDialog = gui.MicroDialog(     children=gui.ExpanderLayout((active, reverse, gravity, "-"),                                 (None, None, gui.HFrame(xField, yField, zField), gui.ExpanderButton()),                                 (positions, "-", "-", "-")))  # Show the MicroDialog show(microDialog)  ############################################################################## 

 

14.  NoteBook Example

from hwx import gui  # This method is called whenever a new Tab is selected. def tabChanged(event):   # Get the label for the current tab   notebook = event.widget   label = notebook.TabLabel(notebook.current)   print(f"Tab selected: {label}")  # Create a NoteBook widget with tabs notebook = gui.NoteBook(flat=False, command=tabChanged)  # Add tabs to the notebook notebook.addTab(gui.LineEdit("First"), text="First") notebook.addTab(gui.LineEdit("Second"), text="Second") notebook.addTab(gui.LineEdit("Third"), text="Third")  show(notebook) 

15. Dialog Box Example

from hwx import gui  # Method called when the 'Close' button is clicked def onClose(event):   gui.tellUser(f'Distance is {distance.value}')   dialog.hide()  # Widgets inside the dialog distance = gui.DoubleEdit(9.81, units='length') height = gui.DoubleEdit(2.91, units='length') close = gui.Button('Close', command=onClose)  # Create a dialog with the widgets dialog = gui.Dialog(   caption="The distance",    children=(     gui.GridFrame(       ("Distance", 5, distance),        ("Height", 5, height)     ), 5, ("<->", close)   ) )  show(dialog) 

16. File Dialog Example

from hwx import gui  filter = ";;".join(   ["Text File (*.txt)", "XML File (*.xml)", "Python File (*.py)", "All Files (*)"])  def getInputFileName():   fname = gui.getOpenFileName(startWith=output.get(), filter=filter, caption="Get open filename")   if fname:     output.set(fname)  def getOutputFileName():   fname = gui.getSaveFileName(startWith=output.get(), filter=filter, caption="Get save filename", confirmOverwrite=True)   if fname:     output.set(fname)  output = gui.LineEdit(width=500)  frame = gui.VFrame(   (gui.Button("Get input file name", command=getInputFileName), "<->"),   (gui.Button("Get output file name", command=getOutputFileName), "<->"),   10, (gui.Label("Selected File Name = "), output) )  show(frame) 

17.  Message Dialog Example

from hwx import gui  # Function called when a button is clicked def buttonClickCommand(buttonId):   if buttonId == 0:     gui.tellUser("Accept button clicked.")   else:     gui.tellUser("Reject button clicked.")  # Create a MessageDialog msg = gui.MessageDialog(message="This is an example for message dialog",                         icon="info", button1="Accept", button2="Reject",                         command=buttonClickCommand)  # Create a button that shows the message dialog when clicked btn = gui.PushButton("Click Me!", command=lambda: msg.show()) show(btn) 

18. Ribbon Example

from hwx import gui from hwx.inspire.demo import getDemoFilePath  # Add icons to resource path resourceFolder = getDemoFilePath('resources') gui.addResourcePath(resourceFolder)  def createRibbon(event):   # Avoid adding duplicate ribbon pages   if gui.RibbonPage.get('Demo Ribbon Page'):     return      page = gui.RibbonPage(name='Demo Ribbon Page')      # Create a group for fastener-related actions   group = gui.SpriteActionGroup(page, text="Fasteners")    gui.SpriteAction(group, tooltip="Add/Edit Fasteners",                    icon=("ribbonFastenersStrip-80.png", (0, 5)))    gui.SpriteAction(group, tooltip="List Bolts/Pins",                    icon=("ribbonSatelliteListStrip-80.png", (3, 5)))  # Button to trigger the ribbon creation button = gui.Button('Create Ribbon', command=createRibbon) show(button) 

19. Widget Stack Example

from hwx import gui  # Action to display the relevant line edit field based on radio button selection def onClick(event):   field = line_edit1 if event.value == "First" else line_edit2   widgetStack.visibleWidget = field  # Create a radio button radio_button = gui.HRadioButtons('First Second', command=onClick)  # Line edits to switch between line_edit1 = gui.LineEdit("First") line_edit2 = gui.LineEdit("Second")  # Create a stack where only one widget is visible at a time widgetStack = gui.WidgetStack(widgets=(line_edit1, line_edit2))  frame = gui.VFrame(radio_button, widgetStack) show(frame) 

20. HBoxLayout Example

HBoxLayout is used to arrange widgets horizontally in a linear fashion. This layout is useful when you need to align components side by side, with optional spacing between them. It helps in organizing the user interface (UI) elements in a row and is especially handy when creating toolbar-like interfaces or horizontally aligned buttons.

from hwx import gui  layout = gui.HBoxLayout (   border   = 5, # padding around all children   spacing  = 3, # padding around each child   children = (     "Button A", gui.Button('A'),     "Button B", gui.Button('B'),     "Button C", gui.Button('C'),   ), )  show (layout) 

 

21. VBoxLayout Example

VBoxLayout is utilized to arrange widgets vertically. This layout is beneficial for stacking components on top of each other, such as aligning buttons or fields in a column. It ensures that all child widgets are neatly stacked, providing a straightforward way to organize vertical arrangements in a user interface.

from hwx import gui  layout = gui.VBoxLayout (   border   = 5, # padding around all children   spacing  = 2, # padding around each child   children = (     gui.Button('A'),     gui.Button('B'),   ), )  show (layout) 

 

22. GridLayout Example

GridLayout arranges widgets in a grid format, allowing for more complex arrangements where widgets are placed in rows and columns. This layout is ideal for forms or tables where alignment across multiple dimensions is required.

from hwx import gui  displacement = gui.DoubleEdit (9.8, units="length") velocity     = gui.DoubleEdit (3.2, units="velocity")  layout = gui.GridLayout(   border   = 5,     # padding around all children   spacing  = (5,2), # padding around each child (horizontal, vertical)   children = (     ("Displacement", displacement),     ("Velocity",     velocity),   ), )  show (layout) 

23. ScrollLayout Example

ScrollLayout is used to create a scrollable area within a user interface. It is beneficial when dealing with large amounts of content that cannot fit within the visible area of the window. This layout allows users to scroll through the content both horizontally and vertically.

from hwx import gui  layout = gui.ScrollLayout(children=[(gui.Label(text="Label: "+str(i)), 10,                                   gui.Button(i), 5) for i in range(1, 51)])  show(layout) 

24. ExpanderLayout Example

ExpanderLayout is used to create a collapsible section within the UI. It allows certain sections of the layout to be expanded or collapsed, which is useful for organizing content that may not always be needed or to reduce clutter.

from hwx import gui  displacement = gui.DoubleEdit (9.8, units="length") velocity     = gui.DoubleEdit (3.2, units="velocity") expander     = gui.ExpanderButton() # click to show/hide following rows  layout = gui.ExpanderLayout(   border   = 5,     # padding around all children   spacing  = (5,2), # padding around each child (horizontal, vertical)   children = (     ("Displacement", displacement, expander),     ("Velocity", velocity, "-"),   ), )  show (layout) 

25. XyPlot Example

XyPlot is used to create XY plots for visualizing data. It provides options for setting plot titles, axis labels, and plot appearance, making it a powerful tool for displaying data trends and relationships graphically.

from hwx import gui from hwx.gui.XyPlot import XyPlot  plot = XyPlot(title="This is the plot Title\nand Subtitle", size=(10, 10),   xlabel="X label", ylabel="Y label", footer="This is the plot footer")  plot.xlimits = (-2.0, 2.0) plot.ylimits = (-1.0, 3.0) plot.bgColor = "lightblue" plot.fontSize = 14 plot.border = 20 plot.numberFormat = "%g" plot.zeroLines = True  show(plot) 

26.  Curve Example

Curve in the context of XyPlot is used to add graphical curves to a plot. This feature allows users to visualize data series or mathematical functions as curves within the plot, with customization options for appearance and interactivity.

from hwx import gui from hwx.gui.XyPlot import XyPlot from hwx.gui.XyPlot import Curve  plot = XyPlot(title="Plot with Curves")  x = [1, 2, 4, 5, 6] y = [1, 3, 4, 1, 7] curve1 = Curve(plot, x=x, y=y, draggable=False, label="Curve1") curve1.color = "red" curve1.linestyle = "dashed" y = ([1, 2, 4, 5, 6], [2, 4, 5, 2, 8]) plot.addCurve(x=x, y=y, draggable=False, label="Curve2") show(plot) 

27. Sliders Example

XSlider and YSlider are used to add interactive sliders to a plot, enabling dynamic adjustments and real-time data visualization. These sliders allow users to interactively modify the plot's parameters and observe changes immediately.

from hwx import gui from hwx.gui.XyPlot import XyPlot from hwx.gui.XyPlot import XSlider, YSlider  plot = XyPlot(title="Plot with Sliders") x = [1, 2, 4, 5, 6] y = [1, 3, 4, 1, 7] plot.addCurve(x=x, y=y, draggable=False, label="Curve1")  xSlider = XSlider(plot, color="red", linestyle="dashed", value=1.0) ySlider = YSlider(plot, color="red", linestyle="dashed", value=1.0)  class MyEventHandler:   def __init__(self, xSlider, ySlider):     self.xSlider = xSlider     self.ySlider = ySlider    def onMouseMove(self, event):     self.xSlider.text = event.x     self.ySlider.text = event.y     return False  plot.addEventHandler(MyEventHandler(xSlider, ySlider)) show(plot) 

28. Clear Example

The clear method is used to remove all content from a plot or layout. This feature is useful when you need to reset the display or remove elements dynamically.

from hwx import gui from hwx.gui.XyPlot import XyPlot  plot = XyPlot(title="XYPlot")  x = [1, 2, 4, 5, 6] y = [1, 3, 4, 1, 7] plot.addCurve(x=x, y=y, draggable=False, label="Curve1") plot.addYslider(y=2.0)  plot.clear() show(plot) 

 

attached the InspirePythonAPIDemo.py file, which contains a comprehensive collection of examples demonstrating various Inspire APIs. This file serves as a valuable resource, offering practical insights and code samples to help you better understand and utilize the Inspire APIs effectively.

Happy Scripting!