Exploring Altair Inspire APIs: A Python Demo for GUI Development
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!