7.3. Gravis Scripting

7.3.1. Introduction

You can add extra functionality to Gravis using Python scripts. Scripts can be

  • launched when Gravis starts up via a command-line option,

  • added as Gravis menus entries, or

  • launched interactively from the Gravis UI.

Scripts can access the loaded RFG, load files, open new windows, scan and manipulate nodes shown in graph windows, apply layouts, etc. Gravis scripting builds on top of RFG scripting (see Section RFG Scripting) and uses some of its Python classes, most notably Graph, View, Node, Edge, Node_Set, and Edge_Set. It also introduces new classes, e. g., Graphical_Node.

You can run a Python script when launching Gravis using the --script<filename> command-line option. The given script is executed immediately after loading any RFG and GXL files mentioned on the command-line. Parameters can be passed to the script via one or more --script-param<parameter> options. If the --quit option is specified as well, then Gravis executes the script in non-interactive mode and quits after execution has finished. This allows Gravis to be used in a batch-processing environment, e.g., to generate PDF or PNG diagrams during a build process.

The section titled Adding Scripts to Menus, Shortcuts and Events describes how to add Python scripts as new menu entries to Gravis.

7.3.1.1. Introductory Example: Generating a Report as CSV File

Before presenting the details of the Gravis scripting interface, let us start with a small example illustrating one of the possible use cases.

The script shown in Listing Example script implementing a CSV export of the attributes of the currently selected nodes generates a report in CSV format. If started from within Gravis, the currently selected nodes in the clicked view are exported.

Example script implementing a CSV export of the attributes of the currently selected nodes
# Copyright (C) 2025 Axivion GmbH
# Copyright (C) 2025 The Qt Company GmbH, a subsidiary of The Qt Group
# https://www.qt.io
# pyright: standard


"""Exports attribute values of a set of nodes to a CSV file."""
import csv
import os.path
import sys

try:
    from bauhaus import gravis
except ImportError:
    gravis = None
    sys.exit(1)


def export_as_csv(filename, attribute_name_list, nodes):
    """Exports the attribute values of attributes in
    attribute_name_list in CSV format for all nodes to filename."""
    csv_writer = csv.writer(
        open(filename, 'w', encoding="utf-8"),
        delimiter=';',  # suitable for German Excel
        quotechar='"',
        quoting=csv.QUOTE_MINIMAL,
    )
    # write header row
    row = []
    for attribute_name in attribute_name_list:
        row.append(attribute_name)
    csv_writer.writerow(row)

    # write body rows
    for current_node in nodes:
        row = []
        for current_attribute_name in attribute_name_list:
            try:
                attr_value = current_node[current_attribute_name]
                row.append(attr_value)
            except KeyError:
                row.append('')
        csv_writer.writerow(row)


if __name__ == '__main__':
    if gravis:
        # if called from within gravis, export Name, File, and Line
        # attributes of the selected nodes in the clicked view
        if not gravis.graph_loaded():
            gravis.error('Need an RFG,\n' 'so please load an RFG file first.')
            sys.exit(1)
        clicked_view = gravis.get_clicked_view()
        if not clicked_view:
            gravis.error(
                'Need a view,\n'
                'so please run this script from the context menu '
                'of a graph window.'
            )
            sys.exit(1)
        else:
            clicked_view = gravis.get_clicked_view()
            assert clicked_view is not None
            nodes = gravis.selected_nodes(clicked_view)
            doit = True
            if not nodes:
                doit = gravis.warning(
                    'There are no nodes selected,\n'
                    'so the resulting file will contain\n'
                    'no attribute data.'
                )
            if doit:
                filename = gravis.get_string(
                    "Query from Gravis Pro",
                    "Full output path",
                    "Please enter a filename to save to",
                )
                if filename is not None and (
                    not os.path.exists(filename)
                    or gravis.confirmation(
                        'File "%s" already exists, overwrite?' % filename
                    )
                ):
                    export_as_csv(
                        filename, ('Source.Name', 'Source.File', 'Source.Line'), nodes
                    )
    else:
        print('this demo is not intended for command line usage')
        sys.exit(1)

We will skip trough the script line by line:

lines

description

1

A docstring explains the purpose of the script.

2 – 4

Import of script modules sys, csv, os.path, and rfg.

5 – 9

Imports gravis if we run inside the Gravis UI. If we run in batch mode, gravis is ’None’.

11–34

Definition of function export_as_csv which does the work.

11

Parameters (and variables) are not typed.

12–13

A docstring explains the purpose of the function. The docstrings for this module and all included functions are displayed in an interactive interpreter session by help(export_as_csv) after the module has been imported.

14–18

Create a csv writer that writes into a file opened for writing (’w’). The quoting characteristics of the csv writer are also configured.

19 – 23

Write the header row. row is a local variable that contains an empty list. The for-loop iterates the names in the parameter attribute_name_list. append is a instance method of type list appending an element to the list. writerow expects a list which it exports as a line in the csv file.

25 – 34

Write the body rows.

25

A for-loop can iterate everything that implements the iterator interface. A set of nodes (a NodeSet) implements the iterator interface, so we can iterate it in the same manner as an ordinary Python list or set.

30

The attributes of a node (and of an edge) can be queried (and set as well) as if the node was a dictionary. Thus we get a KeyError exception if there is no value set, so we have to care for the case that there is no attribute value set. In our case we are not sure if the node has a value for the attribute at all. We chose to use a try except statement. We could also have guarded the test using the condition if current_attribute_name in current_node:.

36 – 72

This part is executed if the script is started stand alone. If the script is imported in another script, the function export_as_csv can be used there. If the script is called from within the gravis UI, the currently selected nodes will be exported. The portion of code necessary for a batch mode usage is left out.

That way, it is possible to combine interactive usage, test code, and library code in one file without fuzz.

41

Check whether an RFG is loaded: gravis.get_graph() is the currently loaded RFG graph displayed in Gravis. If there is no RFG graph loaded, gravis.get_graph() is ’None’.

45

The script context has to supply a view.

50

We have a graph and a view, so proceed: Get the selected nodes.

52

doit is used in case there are no nodes to cancel cvs generation.

54

If there are no nodes selected, ask the user what to do.

59

Ask the user for a filename. Ask for permission to overwrite in case the file already exists.

65

Call the actual payload. Export the attributes Source.Name, Source.File, and Source.Line. The attribute names are as displayed in the UI of Gravis.

7.3.1.2. The Gravis Scripting Environment

In order to access Gravis GUI functionality you need to import the bauhaus.gravis module, see Listing Import module gravis.

Import module gravis
from bauhaus import gravis

After completion of a script, the View Box and all graph windows are updated to reflect any changes made by the script, e.g., created views are shown in the View Box, created nodes and edges are shown in open graph windows and graph windows are updated to reflect changes to the selection or the marking.

Caution

You can access the Gravis related features from within Gravis but not from within rfgscript. An attempt to import gravis inside a script that is executed by rfgscript will raise an ImportError, which you can catch.

It is possible to write scripts that use the gravis GUI when run inside gravis and the console when run via rfgscript. To do so, use the following code at the start of the file:

try:
    import gravis
except ImportError:
    gravis = None

Later on in the script you can then do different things depending on the execution environment. For instance, the script could open a graphical window and apply a layout to it when being run inside gravis as opposed to displaying some text-only output when being run via rfgscript.

if gravis:
    # handle the gravis stuff
else:
    # handle the console stuff

7.3.2. Scripting Interface Reference

Version numbers after functions indicate the version in which the function was added. Functions without version numbers were added before Bauhaus 6.5.0.

7.3.2.1. Global Functions

The RFG Displayed in Gravis

get_graph()
get_graph_filename() (7.7.4, 7.6.9)
new_graph() (6.9.10)
graph_loaded()
close_graph()
open_file(name)
open_rfg_buffer(buffer) (7.0.0)

The function get_graph returns the currently loaded RFG graph. It returns None if no RFG is loaded in the Gravis GUI. The convenience function graph_loaded returns a boolean value indicating whether a graph is loaded. get_graph_filename returns the filename of the loaded graph or the empty string if there is no graph or only a newly created graph that has not been saved yet. close_graph closes and discards the currently loaded graph, if there is one. open_file opens the file name and returns a boolean indicating whether the operation succeeded. open_rfg_buffer opens an RFG file stored in a memory buffer (of type bytes or bytearray) and returns a boolean indicating whether the operation succeeded. new_graph creates a new empty graph with the default schema.

Caution

If there was already an RFG graph loaded when calling open_file, open_rfg_buffer or new_graph, it is discarded and any references to the graph itself, to views, nodes or edges inside that graph or to graphical nodes in open windows still held by the script become invalid. If Gravis is run in non-interactive mode (with --quit), the existing graph is closed without a prompt even if it was modified. The same caveats apply to calling close_graph.

Configuration Information

get_configured_label_font_family() (7.11.5)

get_configured_label_font_family returns the configured font family to use for node and edge labels in graphical views as specified in the /Tools/Gravis/graph_view/label_font_family configuration option. This is a comma-separated list of font family names including the pseudo-fonts serif, sans-serif, monospace and gui.

Context Information

get_script_context() (6.5.2)
argv() (6.8.4)

Scripts can find out in which context they were launched. get_script_context returns one of the following strings:

  • ’Startup’: The script was run by launching Gravis with the --script switch.

  • ’Main’: The script was run from the Main menu.

  • ’View’: The script was run from the context menu over a view in the View Box.

  • ’Window’: The script was run from the context menu of a graph window.

  • ’Internal’: The script implements some internal Gravis functionality and was not launched by the user.

When launching a script from the command-line using the --script switch extra parameters can be passed to it using any number of --script-param <parameter> switches. The script can obtain the list of parameters by calling argv(). Similar to sys.argv(), the first entry of the returned list is the full file name of the script, the remaining entries are the extra parameters specified via --script-param.

get_clicked_view()
get_primary_view()

Many Gravis operations are view-specific, e.g., selection operations. If a script was launched from the context menu of a graph window, or from the context menu of a view in the View Box, then there is a clicked view, which can be obtained by calling get_clicked_view. If the script was run from the main menu, None is returned.

The view shown in the currently active window can be obtained by calling get_primary_view. This works in scripts launched via the main menu or the context menu of a graph window. If the current window has no associated view (e. g., a source code window), it returns None.

Caution

If the active window is a Mapping dialog, which shows two views in a split display, get_primary_view returns the conceptual view edited in the dialog, i.e., the mapping view. If the user launched the script from the context menu over one of the sides of the dialog, get_clicked_view returns the view associated with that part of the dialog.

The returned view is a Python object of class rfg.View.

get_selected_views() (6.5.6)

get_selected_views returns the views that are selected in the View Box as a list of rfg.View objects. This list can be empty if no views are selected. If the View Box is not the active window, None is returned instead.

This method facilitates implementing scripts that operate on more than one view. Users can pass the parameter views to the script conveniently by selecting them in the View Box before running the script. This is particularly useful for scripts that are added to the View Box context menu.

get_selected_node_type_name() (6.6.3)
get_selected_edge_type_name() (6.6.3)

get_selected_node_type_name returns the name of the selected node type in the Node Types panel. The empty string is returned if the current window is not a diagram window or if no type is selected in the window.

get_selected_edge_type_name returns the name of the selected edge type in the Edge Types panel. The empty string is returned if the current window is not a diagram window or if no type is selected in the window.

get_clicked_node() (6.6.3)
get_clicked_node_symbol() (6.6.3)
get_clicked_edge() (6.6.3)

get_clicked_node returns the node on which the user has clicked to launch the script or None if the script was not launched from the context menu of a node in a diagram window (including its expanded background). The returned node is an instance of class rfg.Node.

get_clicked_node_symbol returns the node symbol on which the user has clicked to launch the script or None if the script was not launched from the context menu of a node symbol in a diagram window (excluding its expanded node background). The returned node is an instance of class rfg.Node.

get_clicked_edge returns the edge on which the user has clicked to launch the script or None if the script was not launched from the context menu of an edge in a diagram window. The returned edge is an instance of class rfg.Edge.

get_current_window_type() (6.9.6)
get_windows() (6.9.6)
activate_window(window_index) (6.9.6)

get_current_window_type returns the type of the currently active Gravis window. Possible return values are: none (if there is no active window), viewbox, diagram.graphical.flat (a flat graph window), diagram.graphical.hierarchy (a hierarchical graph window), diagram.tree, diagram.split (for the mapping dialog), diagram.edge_list.basic (for the list of edges shown when double-clicking on a summary edge), diagram.edge_list.violations (for the violations and/or conformances list of architecture analysis), info.node, info.edge, info.view, info.graph (for node/edge/view/graph info windows), source (for source code windows).

get_windows returns the list of open Gravis windows. Each window is represented by a 4-tuple of strings: window type (values as for get_current_window_type), title, primary view, layout. The primary view field is only applicable to window types starting with diagram. and the layout field is only applicable to window types starting with diagram.graphical. Fields that are not applicable are empty. Graphical windows without a persistent layout have an empty layout field.

activate_window activates the window at the given index in the list returned by get_windows.

Opening Graph Windows

open_view(view_or_name, diagram_type)
open_view(view_or_name, diagram_type, layout_name = None) (6.9.6)
get_layouts_for_view(view_or_name) (6.9.6)
extract_selection(view, bool strict = True)
extract_marking(view, bool strict = True)

open_view opens the view view_or_name specified either as a name (using a string) or as an rfg.View object as a new window of type diagram_type. It does nothing if there is no graph or if the named view does not exist. The global variable diagram_types lists the valid values for diagram_type:

  • ’flat’ opens a graphical window without a node hierarchy.

  • ’hierarchy’ opens a graphical window showing a hierarchy of nodes.

  • ’tree’ opens a tree display (always hierarchical).

The name of the persistent layout with which the view should be opened can be passed in layout_name. The special name _default_ opens the view with the default persistent layout. The default value of None opens the view without a persistent layout (as in versions before 6.9.6, which do not support this parameter).

open_view returns True if the window has been opened successfully. In that case, the new window has become the active window and the view has become the clicked view.

get_layouts_for_view returns the names of the persistent layouts that exist for the given view as a list, default layout first.

extract_selection opens a new window for view (specified as a View object, not a name) containing just the selected nodes and edges. If strict is True (default), then only selected entities are included in the new diagram, so selected edges whose endpoints are not both selected as well are omitted. If strict is False, then at least all selected entities are included in the new diagram, so unselected endpoints of selected edges are included, too. Returns True for success, and in that case, the new window has become the active window and view has become the clicked view.

extract_marking works like extract_selection, except that it extracts the marked nodes and edges in view instead of the selected nodes and edges.

Caution

Even though the marking is global and not associated with a particular view, extract_marking only extracts the marked elements of the specified view, not all marked elements.

See below for operations to handle the selection/marking.

User Interaction

get_string(title[, label[, explanation]])
get_string(title[, label[, explanation[, echo_mode]]]) (7.0.11, 7.1.9, 7.2.4)
get_choice(title, label, explanation, choices_list) (6.6.1)
get_choice(title, label, explanation, choices_list, *, as_buttons=False, allow_cancel=True) (7.7.8),(7.8.2)
get_string_choice(title, label, explanation, choices_list, *, as_buttons=False, allow_cancel=True) (7.7.8),(7.8.2)
select_file(title, default_dir, filters, dir_only, must_exist) (6.7.3)

Function get_string pops up a modal dialog asking for user input. The strings title, label and explanation are shown in the title bar, next to the input field and underneath the input field respectively. If the user cancels the input procedure (either by clicking the Cancel button or by closing the dialog) None is returned. The echo_mode parameter controls whether the entered characters are shown normally (echo_mode 'normal', the default), not at all ('no_echo') or as platform-specific password mask characters ('password').

get_choice asks the user to pick one entry from a list of alternatives. choices_list should be a list of strings to display. The other parameters are as for get_string. explanation is optional, it can be left empty if nothing should be displayed underneath the list. The return value is the 0-based index of the chosen alternative, or -1 to indicate that the user has canceled the dialog. If as_buttons is True, the alternatives are presented as a row of push buttons. This is not suitable for a large number of alternatives. If allow_cancel is False, then the dialog has no Cancel button and the user cannot close it by clicking on the window’s close icon.

get_string_choice works like get_choice but instead of an index it returns the chosen string directly or None in case the user canceled the dialog.

select_file displays a file chooser with title in the title bar showing the contents of directory default_dir (can be empty in which case the most recently used directory is shown) and contents filtered by filters. Several filters can be specified, separated by “ ;;“, e. g., “ PNG files (*.png);;JPEG files (*.jpg)“. If dir_only is True, then only directories can be selected. If must_exist is True, then only existing files/directories can be selected. If must_exist is False, then it is assumed that the location will be used for saving, so the user can enter non-existing file/directory names and selecting an existing file displays an “overwrite” warning. An empty string is returned if the user has canceled the dialog.

information(message)
confirmation(message)
warning(message)
error(message)

These four information functions pop up a modal window displaying message. information and error only display an OK button and return no status. confirmation and warning also display a Cancel button and return True if the user confirmed the message by clicking on OK and False if the user clicked on Cancel.

Listing Message display example shows an example.

Message display example
# Copyright (C) 2025 Axivion GmbH
# Copyright (C) 2025 The Qt Company GmbH, a subsidiary of The Qt Group
# https://www.qt.io


from bauhaus import gravis

gravis.information("A neat information about what I do now...")

if gravis.confirmation("Should I do it really that way?"):
    gravis.information("Yes, I will do it this way!")
else:
    gravis.information("No, I will not do it this way!")

if gravis.warning("Should I proceed despite of errors?"):
    gravis.information("Yes, I will keep going!")
else:
    gravis.information("No, I will abort!")

gravis.error("Something serious happened")

Exiting Gravis

exit(rc)

A call to exit terminates the current gravis process. The integer value rc is passed to the operating system as the return code of the process.

Note

A call to sys.exit terminates the gravis process.

7.3.2.2. The Selection

Querying the Selection

selected_nodes(view)
selected_edges(view)

selected_nodes and selected_edges return the selected nodes/edges in view (specified as an rfg.View object). view must belong to the loaded RFG (as returned by get_graph).

Modifying the Selection

select_all_nodes_in_view(view)
select_all_edges_in_view(view)
select_all_in_view(view)
deselect_all_nodes_in_view(view)
deselect_all_edges_in_view(view)
deselect_all_in_view(view)
select_nodes(view, node_set)
set_nodes_selected(view, node_set, b)
select_edges(view, edge_set)
set_edges_selected(view, edge_set, b)

select_all_nodes_in_view, select_all_edges_in_view, select_all_in_view, deselect_all_nodes_in_view, deselect_all_edges_in_view, and deselect_all_in_view select/deselect all nodes/edges/elements in view respectively.

select_nodes selects the nodes in node_set (specified as an rfg.NodeSet object) in view. It clears the selected nodes first, so it effectively replaces the current node selection with the nodes in node_set. If you want to add to the previous selection, use set_nodes_selected instead.

set_nodes_selected sets the selection status of the nodes in node_set in view to b ( True means selected, False means not selected). Unlike select_nodes this does not replace the existing node selection, so this can be used to add to an existing selection or remove nodes from it.

select_edges works like select_nodes, but for edges. set_edges_selected works like set_nodes_selected, but for edges. The parameter edge_set is specified as an rfg.EdgeSet object.

The view must belong to the loaded RFG (as returned from get_graph()). The nodes and edges in node_set and edges_set must be visible in view.

7.3.2.3. The Marking

Querying the Marking

marked_nodes()
marked_edges()

marked_nodes and marked_edges return the marked elements in the graph.

Modifying the Marking

unmark_nodes()
unmark_edges()
unmark_all()
mark_nodes(node_set)
mark_edges(edge_set)

unmark_nodes, unmark_edges, and unmark_all unmark all nodes/edges/elements in the graph.

mark_nodes marks the nodes in node_set (specified as an rfg.NodeSet object). It clears the marked nodes first, so it effectively replaces the set of marked nodes with the nodes in node_set.

mark_edges does the same for edges. The parameter edge_set is specified as an rfg.EdgeSet object. The nodes and edges passed to mark_nodes and mark_edges respectively must belong to the loaded RFG (as returned from get_graph).

Operations on Marked Elements

delete_marking()

delete_marking permanently deletes the marked elements from the graph.

7.3.2.7. Operations for Graphical Windows

The functions in this section only apply to graphical windows (as opposed to other kinds of graph windows, e. g., tree windows). Graphical windows contain the graphical representations of RFG nodes and edges. There is an invisible graphical root node whose children are all top-level nodes. The graphical root and graphical nodes share a common interface, e.g., they both support the ’get_children’ method, so the whole graphical hierarchy can be traversed using a single recursive scan starting from the root.

Graphical Nodes

get_graphical_root()
get_clicked_graphical_node()
get_clicked_graphical_node_symbol()
find_graphical_node(dg_node) (6.6.1)

get_graphical_root returns the invisible root node of the current graphical window as an instance of Graphical_Root. Returns None if there is no current graph window or if the current graph window is not a graphical window.

get_clicked_graphical_node returns the graphical node on which the user has clicked to launch the script or None if the script was not launched from a graphical window or not from the context menu over a node (including its expanded node background). The returned node is an instance of class Graphical_Node.

get_clicked_graphical_node_symbol returns the graphical node symbol on which the user has clicked to launch the script or None if the script was not launched from a graphical window or not from the context menu of a node symbol (excluding its expanded node background).

find_graphical_node returns the graphical representation for dg_node in the current window. The returned node is an instance of class Graphical_Node. Returns None if the current window is not a graphical diagram, dg_node is not visible in the view shown in the current window, or if the graphical representation of dg_node has not been created yet, which can happen if the node is inside a collapsed parent that has not been expanded yet.

Node Hiding

hide_selection()
unhide_selection()
unhide_all()

hide_selection hides all selected nodes and edges from the current graph window. unhide_selection makes all selected nodes and edges that were hidden using hide or hide_selection visible again in the current window. unhide_all() makes all nodes and edges hidden using hide or hide_selection visible again in the current window.

Caution

Whether a node is really displayed in a graph window does not only depend on its “hidden” state. In a hierarchical graphical window, the children of a node that is not expanded are not displayed no matter whether they are hidden or not.

Exporting Window Contents

save_as_png(filename)
save_as_pdf(filename)
save_as_svg(filename) (6.8.3)
create_svg_data() (7.0.0)

save_as_png saves the current window as a PNG bitmap file at the current zoom factor to filename. Returns True if this succeeded.

save_as_pdf/save_as_svg saves the current window as a PDF/SVG file to filename. The output is vector-based and independent of the current zoom factor. Returns True if this succeeded.

create_svg_data returns the SVG representation as a byte string (empty in case of an error or if the current window is not a graphical window).

Other Operations for Graphical Windows

load_layout(filename) (6.5.1)
save_layout(filename) (7.5.11, 7.6.7, 7.7.2)
zoom_to_graph() (6.5.1)
zoom_to_100() (6.5.1)
set_zoom(zoom_factor) (6.9.9)
get_zoom() (6.9.9)
set_center(x, y) (6.9.9)
get_center() (6.9.9)
center_on_node(graphical_node) (6.9.9)
zoom_to_selection() (6.5.1)
zoom_to_marking() (6.5.1)
set_visualization_option(option, state) (6.6.1)

load_layout applies the saved layout from filename to the current graphical window. The file must be in GVL format (file extension .gvl). Returns True if loading succeeded.

save_layout saves the layout of the current graphical window to filename in GVL format. Returns True if saving succeeded. It is recommended that filename ends with .gvl.

zoom_to_graph zooms the window in such a way that the entire graph is visible.

zoom_to_100 resets the zoom factor to its default (100%).

set_zoom sets the zoom factor of the current graphical window to the specified floating-point value zoom_factor. A zoom factor of 1.0 corresponds to 100%.

get_zoom returns the zoom factor of the current graphical window as a floating-point value. A zoom factor of 1.0 corresponds to 100%.

set_center scrolls the current graphical window to show the given scene position (x, y) in its center, if possible. This may not be possible if the window is zoomed out and/or the position is close to the edge of the diagram. You can obtain a graphical node’s scene position via its get_scene_pos() method.

get_center returns the scene position shown in the center of the window as a floating-point tuple (x, y).

center_on_node scrolls the current graphical window to show the given graphical node graphical_node in its center, if possible. This may not be possible if the window is zoomed out and/or the node is close to the edge of the diagram. Note: This requires a graphical node, not a DG node. You can obtain a graphical node for a DG node via find_graphical_node().

zoom_to_selection/zoom_to_marking zoom the window in such a way that the selection/marking is visible.

set_visualization_option controls the options in the Visualization sub-menu. Possible values for option are: ’muted_edges’, ’transparent_edges’, ’edges_behind_nodes’, ’show_lifted_edges’ (only has an effect if the displayed view has lifted edges), ’transparent_backgrounds’, ’show_node_names’, ’show_attributes’. state can be True or False to switch the given option on or off respectively.

Graphical Node Classes

The Gravis scripting interface introduces two new classes: Graphical_Root and Graphical_Node. Both have in common that they can have child nodes, so they share a common interface to deal with them. That makes it easy to scan the node hierarchy recursively, because top-level nodes and child nodes can be handled in the same way. The graphical root and graphical nodes are referred to as graphical areas.

Common interface for Graphical_Root and Graphical_Node

The following graphical area interface is implemented by Graphical_Root and Graphical_Node:

get_parent(self)
is_visible(self)
is_user_hidden(self)
is_expanded(self)
get_child_size(self)
get_children(self, include_invisible = False)
remove_overlaps(self)
layout_children(self, layout_name)

get_parent returns the parent area of this graphical area. This can be an instance of Graphical_Node (for nested nodes), Graphical_Root (for top-level nodes), or it can be None (for the graphical root).

is_visible returns True if this graphical area is visible. The graphical root is always visible.

is_user_hidden returns True if this graphical area has been hidden. Hidden elements are always invisible, but elements that are not hidden are not necessarily always visible, because they could still be inside a collapsed parent or subject to dynamic filtering. The graphical root cannot be hidden.

is_expanded returns True if this graphical area is expanded. The graphical root is always expanded.

get_child_size returns the size of an unexpanded node child of this area as a tuple (width, height) (in pixels at 100% scaling). Nested nodes usually have a smaller child size than their parents.

get_children returns a list of all child nodes of this area in an arbitrary order, not necessarily in z-order. These are instances of Graphical_Node. If ’include_invisible’ is True, invisible nodes (hidden by the user or with a dynamically hidden type) are included, too.

remove_overlaps removes overlaps between child nodes by moving them around. Returns True if any of the nodes were moved.

layout_children applies a named layout to all child nodes. Possible values for layout_name are: ’Grid’, ’Connected grid’, ’Step’, ’Sawtooth’, ’Lineup X’, ’Sawtooth X’, ’Lineup Y’, ’Circle’, ’Circle filled’, ’Stretch XY’, ’Stretch X’, ’Stretch Y’, ’Tighten XY’, ’Tighten X’, ’Tighten Y’, ’Flip X’, ’Flip Y’, ’Tilt left’, ’Tilt right’, ’Rotate left’, ’Rotate right’, ’Rotate by’, ’Sugiyama’, and ’Spring-electrical’.

They implement the layouts as shown on the Visualization menu in Gravis.

Caution

’Rotate by’ opens a dialog box to ask the user for the angle of rotation, so this layout is probably of little use in scripting.

Note

Using the graphical node interface described further below, you can implement your own layout algorithms by setting node positions directly.

The Graphical_Root Class

There is only one instance of Graphical_Root per graphical window. It can be retrieved by calling get_graphical_root (see Section Graphical Nodes). Graphical_Root objects implement the common graphical area interface (see Section Common interface for Graphical_Root and Graphical_Node) and offer no additional methods.

The Graphical_Node Class

The following methods deal with the graph structure:

get_parent_node(self)
get_dg_node(self)
get_successors(self, include_invisible = False)
get_predecessors(self, include_invisible = False)
get_typed_successors(self, include_invisible = False)
get_typed_predecessors(self, include_invisible = False)

get_parent_node returns the parent node of this node or None if this node is at the top level. Not to be confused with get_parent in the common graphical area interface (see Section Common interface for Graphical_Root and Graphical_Node).

get_dg_node returns the RFG node with which this graphical node is associated. This is an instance of class rfg.Node.

get_successors returns a list of all successor nodes of this graphical node, in an arbitrary order. These are instances of Graphical_Node, too. Only returns nodes that are currently visible (not individually hidden by the user, not of a type that is currently hidden, not inside a collapsed parent/ancestor) and that are reachable via a visible edge, unless include_invisible is True, in which case node and edge visibility does not make any difference.

get_predecessors returns a list of all predecessor nodes of this graphical node, in an arbitrary order. These are instances of Graphical_Node, too. See get_successors for the meaning of the include_invisible flag.

get_types_successors returns the typed successors of the node, i.e., successors annotated with the types of the edges leading to them. For each outgoing edge the returned list contains a pair (t, s), where t is the type of the edge and s is the target node of the edge. The list is in an arbitrary order. If there are multiple edges from this node to another node, then each of the edges appears as a list entry. See get_successors for the meaning of the include_invisible flag.

get_types_predecessors returns the typed predecessors of the node similar to See get_types_successors.

The following methods deal with graphical properties:

get_pos(self)
set_pos(self, x, y)
get_scene_pos(self)
get_symbol_size(self)
get_size(self)
get_bbox(self) (7.6.10, 7.7.4)
expand(self)
collapse(self)
hide(self)
unhide(self)
bring_to_front(self)
put_to_back(self)
shrink_to_fit(self)
set_expanded_size(self, width, height)

Note

The base unit for all position and size values is a screen pixel at 100% scaling. All values are scaling independent.

get_pos returns the position of this graphical node within its parent as a floating point tuple (x, y).

set_pos sets the position of this node within its parent node. If the parent node is a graphical node, then x and y should not be negative. If the parent node is the graphical root, then negative coordinates are allowed.

get_scene_pos returns the absolute position of this graphical node in the complete scene as a floating point tuple (x, y). Scene coordinates are suitable for passing to set_center().

get_symbol_size returns the size of the node symbol (independent of the node’s expansion state) as a floating point tuple (width, height).

get_size returns the current size of the node according to its current expansion state as a floating point tuple (width, height).

get_bbox returns the graphical bounding box of the node as a floating point tuple (x, y, width, height). This can be larger than the return value of get_size if there are long labels. x and y are in the node’s own coordinate space and can be negative (e.g., x is negative if the node is collapsed and has a centered label and y is negative if there is a label at the top).

expand expands the node if it is not already expanded.

collapse collapses the node if it is not already collapsed.

hide hides the node. It will no longer be shown in the diagram until it is unhidden using unhide. Has no effect if the node is already hidden.

unhide unhides a node that has been hidden, so it is shown in the diagram again (other circumstances allowing). Has no effect if the node was not hidden.

bring_to_front makes the node appear at the top of the stacking order relative to its siblings. Only makes a difference if the nodes overlap.

put_to_back makes the node appear at the bottom of the stacking order relative to its siblings. Only makes a difference if the nodes overlap.

shrink_to_fit shrinks the node’s expanded size to fit its children. Should only be called for nodes that are currently visible and expanded.

set_expanded_size sets the width and height of the expanded area of this node. Note: The area may be enlarged to encompass all child nodes.