Effective Output/Input

Tables

../_images/tableoutput.png

work in progress

Code Output

../_images/codeoutput.png

work in progress

Progress bars

../_images/progressbaroutput.png

work in progress

Standard Prompts

Alerts

../_images/forms-alert.png
pyrevit.forms.alert(msg, title=None, sub_msg=None, expanded=None, footer='', ok=True, cancel=False, yes=False, no=False, retry=False, warn_icon=True, options=None, exitscript=False)

Show a task dialog with given message.

Parameters:
  • msg (str) – message to be displayed
  • title (str, optional) – task dialog title
  • ok (bool, optional) – show OK button, defaults to True
  • cancel (bool, optional) – show Cancel button, defaults to False
  • yes (bool, optional) – show Yes button, defaults to False
  • no (bool, optional) – show NO button, defaults to False
  • retry (bool, optional) – show Retry button, defaults to False
  • options (list[str], optional) – list of command link titles in order
  • exitscript (bool, optional) – exit if cancel or no, defaults to False
Returns:

True if okay, yes, or retry, otherwise False

Return type:

bool

Example

>>> from pyrevit import forms
>>> forms.alert('Are you sure?',
...              ok=False, yes=True, no=True, exitscript=True)
../_images/forms-check_workshared.png
pyrevit.forms.check_workshared(doc=None, message='Model is not workshared.')

Verify if model is workshared and notify user if not.

Parameters:
  • doc (DB.Document) – target document, current of not provided
  • message (str) – prompt message if returning False
Returns:

True if doc is workshared

Return type:

bool

../_images/forms-WarningBar.png
class pyrevit.forms.WarningBar(height=32, **kwargs)

Show warning bar at the top of Revit window.

Parameters:title (string) – warning bar text

Example

>>> with WarningBar(title='my warning'):
...    # do stuff

Command Options

../_images/forms-CommandSwitchWindow.png
class pyrevit.forms.CommandSwitchWindow(context, title, width, height, **kwargs)

Standard form to select from a list of command options.

Parameters:
  • context (list[str]) – list of command options to choose from
  • switches (list[str]) – list of on/off switches
  • message (str) – window title message
  • config (dict) – dictionary of config dicts for options or switches
  • recognize_access_key (bool) – recognize ‘_’ as mark of access key
Returns:

name of selected option

Return type:

str

Returns:

if switches option is used, returns a tuple of selection option name and dict of switches

Return type:

tuple(str, dict)

Example

This is an example with series of command options:

>>> from pyrevit import forms
>>> ops = ['option1', 'option2', 'option3', 'option4']
>>> forms.CommandSwitchWindow.show(ops, message='Select Option')
'option2'

A more advanced example of combining command options, on/off switches, and option or switch configuration options:

>>> from pyrevit import forms
>>> ops = ['option1', 'option2', 'option3', 'option4']
>>> switches = ['switch1', 'switch2']
>>> cfgs = {'option1': { 'background': '0xFF55FF'}}
>>> rops, rswitches = forms.CommandSwitchWindow.show(
...     ops,
...     switches=switches
...     message='Select Option',
...     config=cfgs,
...     recognize_access_key=False
...     )
>>> rops
'option2'
>>> rswitches
{'switch1': False, 'switch2': True}

Showing Progress

../_images/forms-ProgressBar.png
class pyrevit.forms.ProgressBar(height=32, **kwargs)

Show progress bar at the top of Revit window.

Parameters:
  • title (string) – progress bar text, defaults to 0/100 progress format
  • indeterminate (bool) – create indeterminate progress bar
  • cancellable (bool) – add cancel button to progress bar
  • step (int) – update progress intervals

Example

>>> from pyrevit import forms
>>> count = 1
>>> with forms.ProgressBar(title='my command progress message') as pb:
...    # do stuff
...    pb.update_progress(count, 100)
...    count += 1

Progress bar title could also be customized to show the current and total progress values. In example below, the progress bar message will be in format “0 of 100”

>>> with forms.ProgressBar(title='{value} of {max_value}') as pb:

By default progress bar updates the progress every time the .update_progress method is called. For operations with a large number of max steps, the gui update process time will have a significate effect on the overall execution time of the command. In these cases, set the value of step argument to something larger than 1. In example below, the progress bar updates once per every 10 units of progress.

>>> with forms.ProgressBar(title='message', steps=10):

Progress bar could also be set to indeterminate for operations of unknown length. In this case, the progress bar will show an infinitely running ribbon:

>>> with forms.ProgressBar(title='message', indeterminate=True):

if cancellable is set on the object, a cancel button will show on the progress bar and .cancelled attribute will be set on the ProgressBar instance if users clicks on cancel button:

>>> with forms.ProgressBar(title='message',
...                        cancellable=True) as pb:
...    # do stuff
...    if pb.cancelled:
...        # wrap up and cancel operation

Standard Dialogs

Pick File

../_images/forms-pick_file.png
pyrevit.forms.pick_file(file_ext='', files_filter='', init_dir='', restore_dir=True, multi_file=False, unc_paths=False)

Pick file dialog to select a destination file.

Parameters:
  • file_ext (str) – file extension
  • files_filter (str) – file filter
  • init_dir (str) – initial directory
  • restore_dir (bool) – restore last directory
  • multi_file (bool) – allow select multiple files
  • unc_paths (bool) – return unc paths
Returns:

file path or list of file paths if multi_file=True

Return type:

str or list[str]

Example

>>> from pyrevit import forms
>>> forms.pick_file(file_ext='csv')
... r'C:\output\somefile.csv'
>>> forms.pick_file(file_ext='csv', multi_file=True)
... [r'C:\output\somefile1.csv', r'C:\output\somefile2.csv']
>>> forms.pick_file(files_filter='All Files (*.*)|*.*|'
                                 'Excel Workbook (*.xlsx)|*.xlsx|'
                                 'Excel 97-2003 Workbook|*.xls',
                    multi_file=True)
... [r'C:\output\somefile1.xlsx', r'C:\output\somefile2.xls']
pyrevit.forms.save_file(file_ext='', files_filter='', init_dir='', default_name='', restore_dir=True, unc_paths=False)

Save file dialog to select a destination file for data.

Parameters:
  • file_ext (str) – file extension
  • files_filter (str) – file filter
  • init_dir (str) – initial directory
  • default_name (str) – default file name
  • restore_dir (bool) – restore last directory
  • unc_paths (bool) – return unc paths
Returns:

file path

Return type:

str

Example

>>> from pyrevit import forms
>>> forms.save_file(file_ext='csv')
... r'C:\output\somefile.csv'

Pick Folder

../_images/forms-pick_folder.png
pyrevit.forms.pick_folder(title=None)

Show standard windows pick folder dialog.

Parameters:title (str, optional) – title for the window
Returns:folder path
Return type:str

Select Views

../_images/forms-select_views.png
pyrevit.forms.select_views(title='Select Views', button_name='Select', width=500, multiple=True, filterfunc=None, doc=None)

Standard form for selecting views.

Parameters:
  • title (str, optional) – list window title
  • button_name (str, optional) – list window button caption
  • width (int, optional) – width of list window
  • multiselect (bool, optional) – allow multi-selection (uses check boxes). defaults to True
  • filterfunc (function) – filter function to be applied to context items.
  • doc (DB.Document, optional) – source document for views; defaults to active document
Returns:

list of selected views

Return type:

list[DB.View]

Example

>>> from pyrevit import forms
>>> forms.select_views()
... [<Autodesk.Revit.DB.View object>,
...  <Autodesk.Revit.DB.View object>]

Select Sheets

../_images/forms-select_sheets.png
pyrevit.forms.select_sheets(title='Select Sheets', button_name='Select', width=500, multiple=True, filterfunc=None, doc=None)

Standard form for selecting sheets.

Sheets are grouped into sheet sets and sheet set can be selected from a drop down box at the top of window.

Parameters:
  • title (str, optional) – list window title
  • button_name (str, optional) – list window button caption
  • width (int, optional) – width of list window
  • multiselect (bool, optional) – allow multi-selection (uses check boxes). defaults to True
  • filterfunc (function) – filter function to be applied to context items.
  • doc (DB.Document, optional) – source document for sheets; defaults to active document
Returns:

list of selected sheets

Return type:

list[DB.ViewSheet]

Example

>>> from pyrevit import forms
>>> forms.select_sheets()
... [<Autodesk.Revit.DB.ViewSheet object>,
...  <Autodesk.Revit.DB.ViewSheet object>]

Select Revisions

../_images/forms-select_revisions.png
pyrevit.forms.select_revisions(title='Select Revision', button_name='Select', width=500, multiple=True, filterfunc=None, doc=None)

Standard form for selecting revisions.

Parameters:
  • title (str, optional) – list window title
  • button_name (str, optional) – list window button caption
  • width (int, optional) – width of list window
  • multiselect (bool, optional) – allow multi-selection (uses check boxes). defaults to True
  • filterfunc (function) – filter function to be applied to context items.
  • doc (DB.Document, optional) – source document for revisions; defaults to active document
Returns:

list of selected revisions

Return type:

list[DB.Revision]

Example

>>> from pyrevit import forms
>>> forms.select_revisions()
... [<Autodesk.Revit.DB.Revision object>,
...  <Autodesk.Revit.DB.Revision object>]

Select From Open Documents

../_images/forms-select_dest_docs.png
pyrevit.forms.select_open_docs(title='Select Open Documents', button_name='OK', width=500, multiple=True, filterfunc=None)

Standard form for selecting open documents.

Parameters:
  • title (str, optional) – list window title
  • button_name (str, optional) – list window button caption
  • width (int, optional) – width of list window
  • multiselect (bool, optional) – allow multi-selection (uses check boxes). defaults to True
  • filterfunc (function) – filter function to be applied to context items.
Returns:

list of selected documents

Return type:

list[DB.Document]

Example

>>> from pyrevit import forms
>>> forms.select_open_docs()
... [<Autodesk.Revit.DB.Document object>,
...  <Autodesk.Revit.DB.Document object>]

Select From List (Single, Multiple)

../_images/forms-SelectFromList.png ../_images/forms-SelectFromCheckBoxes.png
class pyrevit.forms.SelectFromList(context, title, width, height, **kwargs)

Standard form to select from a list of items.

Any object can be passed in a list to the context argument. This class wraps the objects passed to context, in TemplateListItem. This class provides the necessary mechanism to make this form work both for selecting items from a list, and from a list of checkboxes. See the list of arguments below for additional options and features.

Parameters:
  • context (list[str] or dict[list[str]]) – list of items to be selected from OR dict of list of items to be selected from. use dict when input items need to be grouped e.g. List of sheets grouped by sheet set.
  • title (str, optional) – window title. see super class for defaults.
  • width (int, optional) – window width. see super class for defaults.
  • height (int, optional) – window height. see super class for defaults.
  • button_name (str, optional) – name of select button. defaults to ‘Select’
  • name_attr (str, optional) – object attribute that should be read as item name.
  • multiselect (bool, optional) – allow multi-selection (uses check boxes). defaults to False
  • return_all (bool, optional) – return all items. This is handly when some input items have states and the script needs to check the state changes on all items. This options works in multiselect mode only. defaults to False
  • filterfunc (function) – filter function to be applied to context items.
  • group_selector_title (str) – title for list group selector. defaults to ‘List Group’
  • default_group (str) – name of defautl group to be selected

Example

>>> from pyrevit import forms
>>> items = ['item1', 'item2', 'item3']
>>> forms.SelectFromList.show(items, button_name='Select Item')
>>> ['item1']
>>> from pyrevit import forms
>>> ops = [viewsheet1, viewsheet2, viewsheet3]
>>> res = forms.SelectFromList.show(ops,
...                                 multiselect=False,
...                                 name_attr='Name',
...                                 button_name='Select Sheet')
>>> from pyrevit import forms
>>> ops = {'Sheet Set A': [viewsheet1, viewsheet2, viewsheet3],
...        'Sheet Set B': [viewsheet4, viewsheet5, viewsheet6]}
>>> res = forms.SelectFromList.show(ops,
...                                 multiselect=True,
...                                 name_attr='Name',
...                                 group_selector_title='Sheet Sets',
...                                 button_name='Select Sheets')

This module also provides a wrapper base class TemplateListItem for when the checkbox option is wrapping another element, e.g. a Revit ViewSheet. Derive from this base class and define the name property to customize how the checkbox is named on the dialog.

>>> from pyrevit import forms
>>> class MyOption(forms.TemplateListItem)
...    @property
...    def name(self):
...        return '{} - {}{}'.format(self.item.SheetNumber,
...                                  self.item.SheetNumber)
>>> ops = [MyOption('op1'), MyOption('op2', True), MyOption('op3')]
>>> res = forms.SelectFromList.show(ops,
...                                 multiselect=True,
...                                 button_name='Select Item')
>>> [bool(x) for x in res]  # or [x.state for x in res]
[True, False, True]
class pyrevit.forms.TemplateListItem(orig_item, checkable=True, name_attr=None)

Base class for checkbox option wrapping another object.

Base Forms

Generic Forms

class pyrevit.forms.TemplatePromptBar(height=32, **kwargs)

Template context-manager class for creating prompt bars.

Prompt bars are show at the top of the active Revit window and are designed for better prompt visibility.

Parameters:
  • height (int) – window height
  • **kwargs – other arguments to be passed to _setup()
class pyrevit.forms.TemplateUserInputWindow(context, title, width, height, **kwargs)

Base class for pyRevit user input standard forms.

Parameters:
  • context (any) – window context element(s)
  • title (str) – window title
  • width (int) – window width
  • height (int) – window height
  • **kwargs – other arguments to be passed to _setup()
class pyrevit.forms.WPFWindow(xaml_source, literal_string=False, handle_esc=True)

WPF Window base class for all pyRevit forms.

Parameters:
  • xaml_source (str) – xaml source filepath or xaml content
  • literal_string (bool) – xaml_source contains xaml content, not filepath
  • handle_esc (bool) – handle Escape button and close the window

Example

>>> from pyrevit import forms
>>> layout = '<Window ' \
>>>          'xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" ' \
>>>          'xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" ' \
>>>          'ShowInTaskbar="False" ResizeMode="NoResize" ' \
>>>          'WindowStartupLocation="CenterScreen" ' \
>>>          'HorizontalContentAlignment="Center">' \
>>>          '</Window>'
>>> w = forms.WPFWindow(layout, literal_string=True)
>>> w.show()

Graphs

Step 1: Create a chart object for the chart type that you want. We’ll add data to this later…

from pyrevit import script

output = script.get_output()

# Line chart
chart = output.make_line_chart()
# Bar chart
chart = output.make_bar_chart()
# Bubble chart
chart = output.make_bubble_chart()
# Radar chart
chart = output.make_radar_chart()
# Polar chart
chart = output.make_polar_chart()
# Pie chart
chart = output.make_pie_chart()
# Doughnut chart
chart = output.make_doughnut_chart()

Step 1-a: Optional: Setup the chart title, and other options. the full list of options for every chart is available on Charts.js Documentation page. Some of the properties have their own sub-properties, for example the title option for the charts has multiple sub-properties as shown below. The value for these type of properties should be a dictionary of the sub-properties you’d like to set. All this is explained clearly in the Charts.js Documentation

chart.set_style('height:150px')

chart.options.title = {'display': True,
                       'text':'Chart Title',
                       'fontSize': 18,
                       'fontColor': '#000',
                       'fontStyle': 'bold'}

Step 2: Now let’s add data to the chart. Every chart object has a data property chart.data that we can interact with to add datasets to the chart. Different types of charts need different types of data sets in terms of how data is organized, so the chart can present multiple data sets correctly. I’m providing two examples here, one for a simple line chart (showing 3 different data sets) and another for a radial chart (also showing 3 different data sets within the same chart). They’re all very similar to each other though.

# setting the charts x line data labels
chart.data.labels = ['Monday', 'Tuesday',
                     'Wednesday', 'Thursday',
                     'Friday', 'Saturday', 'Sunday']

# Let's add the first dataset to the chart object
# we'll give it a name: set_a
set_a = chart.data.new_dataset('set_a')
# And let's add data to it.
# These are the data for the Y axis of the graph
# The data length should match the length of data for the X axis
set_a.data = [12, 19, 3, 17, 6, 3, 7]
# Set the color for this graph
set_a.set_color(0xFF, 0x8C, 0x8D, 0.8)

Step 3: The last step is to ask the chart object to draw itself.

# Before drawing the chart you can randomize the colors
# if you have not added any color to the datasets.
chart.randomize_colors()

# Finally let's draw the chart
chart.draw()

Line charts

See the comments in the script for more info

# get line chart object
chart = output.make_line_chart()

# this is a list of labels for the X axis of the line graph
chart.data.labels = ['Monday', 'Tuesday',
                     'Wednesday', 'Thursday',
                     'Friday', 'Saturday', 'Sunday']

# Let's add the first dataset to the chart object
# we'll give it a name: set_a
set_a = chart.data.new_dataset('set_a')
# And let's add data to it.
# These are the data for the Y axis of the graph
# The data length should match the length of data for the X axis
set_a.data = [12, 19, 3, 17, 6, 3, 7]
# Set the color for this graph
set_a.set_color(0xFF, 0x8C, 0x8D, 0.8)
# You can also set custom options for this graph
# See the Charts.js documentation for all the options
set_b.fill = False

# Same as above for a new data set: set_b
set_b = chart.data.new_dataset('set_b')
# Obviously a different set of data and a different color
set_b.data = [2, 29, 5, 5, 2, 3, 10]
set_b.set_color(0xFF, 0xCE, 0x56, 0.8)

# Same as above for a new data set: set_c
set_c = chart.data.new_dataset('set_c')
# Obviously a different set of data and a different colorset_c.data = [55, 12, 2, 20, 18, 6, 22]
set_c.set_color(0x36, 0xA2, 0xEB, 0.8)

And here is the result:

../_images/linechart.png

Pie charts

See the comments in the script for more info

# get pie chart object
chart = output.make_pie_chart()

# Set the labels for the circumference axis
chart.data.labels = ['A', 'B', 'C']

# Create new data sets
set_a = chart.data.new_dataset('set_a')
set_a.data = [100, 20, 50]
# You can set a different color for each pie of the chart
set_a.backgroundColor = ["#560764", "#1F6CB0", "#F98B60"]

set_b = chart.data.new_dataset('set_b')
set_b.data = [50, 30, 80]
set_b.backgroundColor = ["#913175", "#70A3C4", "#FFC057"]

set_c = chart.data.new_dataset('set_c')
set_c.data = [40, 20, 10]
set_c.backgroundColor = ["#DD5B82", "#E7E8F5", "#FFE084"]

And here is the result:

../_images/piechart.png

Bar charts

See the comments in the script for more info

# get bar chart object
chart = output.make_bar_chart()

And here is the result:

../_images/barchart.png

Bubble charts

See the comments in the script for more info

# get bubble chart object
chart = output.make_bubble_chart()

And here is the result:

../_images/bubblechart.png

Radar charts

See the comments in the script for more info

# get radar chart object
chart = output.make_radar_chart()

And here is the result:

../_images/radarchart.png

Polar Area charts

See the comments in the script for more info

# get polar chart object
chart = output.make_polar_chart()

And here is the result:

../_images/polarareachart.png

Doghnut charts

See the comments in the script for more info

# get doughnut chart object
chart = output.make_doughnut_chart()

And here is the result:

../_images/doghnutchart.png

Charts engine

Here is a little info on how the charts engine works: the pyRevit charts module is pyrevit.coreutils.charts. This is the module that the output window interacts with to create the charts.

The charts module provides the chart object and handles the creation of datasets. The first thing it does when drawing the graph is to create a html <canvas> element and assign a unique id to it:

<canvas id="chart123456"></canvas>

Then it parses the input data and creates a JSON representation of the data. The JSON string (json_data) will be inserted into a template javascript. This javascript creates a Chart object from the Chart.js library:

var ctx = document.getElementById('{}').getContext('2d');
var chart = new Chart(ctx, json_data);

and finally, the pyRevit chart object, injects this dynamically created javascript into the <head> of the output window WebBrowser component:

output.inject_script(js_code)