0% found this document useful (0 votes)
157 views1 page

Forms - Revit Python Wrapper 1.7.4 Documentation

Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
157 views1 page

Forms - Revit Python Wrapper 1.7.4 Documentation

Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd

 Revit Python Wrapper

Docs » [Link] » Forms  Edit on GitHub


latest

Search docs

Forms
Revit Python Wrapper

Installa on The forms module provide several pre-build forms as well as a framework from which you can build
rpw and [Link] your own forms.

[Link]
All classes documented in this sec on can be imported as such:
 [Link]

 Forms
>>> from [Link] import Console
 QuickForms

SelectFromList

TextInput
QuickForms

SelectFromList
TaskDialogs
 OS Dialogs

Console
 FlexForm

Implementa ons

Selec on

[Link]

rpw.u ls

[Link]

[Link] ons

Known Issues

 Read the Docs v: latest 

[Link]( tle, op ons, descrip on=None, sort=True, exit_on_close=True)

Simple FlexForm wrapped func on with ComboBox and bu on

Parameters: tle (str) – Title of form


op ons (dict,list[str]) – Dic onary (string keys) or List[strings]
descrip on (str) – Op onal Descrip on of input requested [default: None]
sort (bool) – Op onal sort flag - sorts keys [default: True]
exit_on_close (bool) – Form will call [Link]() if Closed on X. [default: True]

Usage:

>>> from [Link] import SelectFromList


>>> value = SelectFromList('Test Window', ['1','2','3'])
>>> # Dropdown shows '1', '2' ,'3'. User clicks Select '1'
>>> print(value)
'1'
>>> # Dictionary
>>> value = SelectFromList('Test Window', {'Text':str, 'Number':int})
>>> # User clicks Text
>>> print(value)
str

TextInput

[Link]( tle, default=None, descrip on=None, sort=True, exit_on_close=True)

Simple FlexForm wrapped func on with TextBox and bu on

Parameters: tle (str) – Title of form


default (str) – Op onal default value for text box [default: None]
descrip on (str) – Op onal Descrip on of input requested [default: None]
exit_on_close (bool) – Form will call [Link]() if Closed on X. [default: True]

Usage:

>>> from [Link] import TextInput


>>> value = TextInput('Title', default="3")
>>> print(value)
3

TaskDialogs
TaskDialog

class [Link](instruc on, commands=None, bu ons=None, tle='Task Dialog', content='',


tle_prefix=False, show_close=False, footer='', expanded_content='', verifica on_text='')

Task Dialog Wrapper

>>> from [Link] import CommandLink, TaskDialog


>>> commands= [CommandLink('Open Dialog', return_value='Open'),
>>> ... CommandLink('Command', return_value=lambda: True)]
>>> ...
>>> dialog = TaskDialog('This TaskDialog has Buttons ',
>>> ... title_prefix=False,
>>> ... content="Further Instructions",
>>> ... commands=commands,
>>> ... buttons=['Cancel', 'OK', 'RETRY'],
>>> ... footer='It has a footer',
>>> ... # verification_text='Add Verification Checkbox',
>>> ... # expanded_content='Add Expanded Content',
>>> ... show_close=True)
>>> [Link]()
'Open'

Wrapped Element:

self._revit_object = [Link]

Parameters: content (str) – Main text of TaskDialog.


commands (list, op onal) – List of CommandLink Instances. Default is no bu ons.
bu ons (list, op onal) – List of TaskDialogCommonBu ons names. Default is no
bu ons. ‘Close’ is shown if no commands are passed.
tle (str, op onal) – Title of TaskDialog. Default is ‘Task Dialog’.p
instruc on (str, op onal) – Main Instruc on.
footer (str, op onal) – Footer Text. Default is blank .
expanded_content (str, op onal) – Expandable Text. Default is blank .
verifica on_text (str, op onal) – Checkbox text. Default is blank .
tle_prefix (bool, op onal) – Prefix Title with app name. Default is False

show_close (bool, op onal) – Show X to close. Default is False.

__init__(instruc on, commands=None, bu ons=None, tle='Task Dialog', content='', tle_prefix=False,


show_close=False, footer='', expanded_content='', verifica on_text='')

Child classes can use self._revit_object to refer back to Revit Element

 Warning

Any Wrapper that inherits and overrides __init__ class MUST ensure _revit_object is
created by calling super().__init__ before se ng any self a ributes. Not doing so will
cause recursion errors and Revit will crash. BaseObjectWrapper should define a class
variable _revit_object_class to define the object class being wrapped.

show(exit=False)

Show TaskDialog

Parameters: exit (bool, op onal) – Exit Script a er Dialog. Useful for displaying Errors. Default
is False.

Returns: Returns is False if dialog is Cancelled (X or Cancel bu on). If CommandLink


bu on is clicked, CommandLink.return_value is returned - if one was not provided,
[Link] is used. If CommonBu ons are clicked
[Link] name is returned ie(‘Close’, ‘Retry’, ‘Yes’, etc).

class [Link](text, subtext='', return_value=None)

Command Link Helper Class

Usage:

>>> from [Link] import CommandLink, TaskDialog


>>> CommandLink('Open Dialog', return_value=func_to_open)
>>> TaskDialog('Title', commands=[CommandLink])

Parameters: text (str) – Command Text


subtext (str, op onal) – Bu on Subtext
return_value (any, op onal) – Value returned if bu on is clicked. If none is
provided, text is returned.

__init__(text, subtext='', return_value=None)

x.__init__(…) ini alizes x; see help(type(x)) for signature

Alert

class [Link](content, tle='Alert', header='', exit=False)

A Simple Revit TaskDialog for displaying quick messages

Usage:

>>> from [Link] import Alert


>>> Alert('Your Message', title="Title", header="Header Text")
>>> Alert('You need to select Something', exit=True)

Parameters: message (str) – TaskDialog Content


tle (str, op onal) – TaskDialog Title
header (str, op onal) – TaskDialog content header
exit (bool, op onal) – Exit Script a er Dialog. Useful for displayin Errors. Default is
False

OS Dialogs
Select Folder

[Link].select_folder()

Selects a Folder Path using the standard OS Dialog. Uses [Link](). For
more informa on see: h ps://[Link] .com/en-
us/library/[Link]filedialog.

>>> from [Link] import select_folder


>>> folderpath = select_folder()
'C:\folder\path'

Select File

[Link].select_file(extensions='All Files (*.*)|*.*', tle='Select File', mul ple=False,


restore_directory=True)

Selects a File Path using the standard OS Dialog. Uses [Link]


h ps://[Link] .com/en-us/library/[Link].filedialog.filter

>>> from [Link] import select_file


>>> filepath = select_file('Revit Model (*.rvt)|*.rvt')
'C:\folder\[Link]'

Parameters: extensions (str, op onal) – File Extensions Filtering op ons. Default is All Files
(.)|*.*
tle (str, op onal) – File Extensions Filtering op ons
mul ple (bool) – Allow selec on of mul ple files. Default is False
restore_directory (bool) – Restores the directory to the previously selected
directory before closing

Returns: filepath string if multiple=False otherwise list of filepath strings

Return type: filepath (list, string)

Console

REPL Console for Inspec ng Stack

>>> from [Link] import Console


>>> Console()
# Console is launched with locally defined variables injected into context.

Keyboard Shortcuts:

UP Iterate history up
Down Iterate history down
Tab Iterate possible autocomplete op ons (works for do ed lookup)

 Note

The last stack frame is automa cally injected is the context of the evalua on loop of the
console: the local and global variables from where the Console was called from should be
available.

Inspec on of the stack requires stack frames to be enabled. If an excep on is raised sta ng
`object has no attribute '_getframe' it means IronPython stack frames is not enabled. You can

enable it by running with the -X argument: [Link] -X: FullFrames [Link] .

If you are trying to use it from within Dynamo, stack inspec on is currently not available due to
how the engine is setup, but you can s ll use it by manually passing the context you want to
inspect:

>>> Console(context=locals()) # or
>>> Console(context=globals())

class [Link](stack_level=1, stack_info=True, context=None, msg='')

__init__(stack_level=1, stack_info=True, context=None, msg='')

Parameters: stack_level (int) – Default is 1. 0 Is the Console stack, 1 is the caller; 2 is


previous to that, etc.
stack_info – Display info about where call came from. Will print filename
name, line no. and Caller name.

FlexForm

class [Link]( tle, components, **kwargs)

Flex Form Usage

>>> from [Link] import (FlexForm, Label, ComboBox, TextBox, TextBox,


... Separator, Button, CheckBox)
>>> components = [Label('Pick Style:'),
... ComboBox('combobox1', {'Opt 1': 10.0, 'Opt 2': 20.0}),
... Label('Enter Name:'),
... TextBox('textbox1', Text="Default Value"),
... CheckBox('checkbox1', 'Check this'),
... Separator(),
... Button('Select')]
>>> form = FlexForm('Title', components)
>>> [Link]()
>>> # User selects `Opt 1`, types 'Wood' in TextBox, and select Checkbox
>>> [Link]
{'combobox1': 10.0, 'textbox1': 'Wood', 'checkbox': True}

__init__( tle, components, **kwargs)

Parameters: tle ( str ) – Form Title


components ( list ) – List of Form Components.
top_offset ( float ) – Op onal top offset.
op ons ( kwargs ) – WPF Parameters Op ons

values

Dic onary of selected values

Type: dict

close()

Exits Form. Returns True to show() method

sta c get_values(sender, e)

Default Get Values. Set [Link] a ribute with values from controls and closes form.

show()

Ini alizes Form. Returns True or False if form was exited.

FlexForm Controls

class [Link](label_text, **kwargs)

[Link] Wrapper

>>> Label('Label Text')

__init__(label_text, **kwargs)

Parameters: label_text ( str ) – Label Text


wpf_params (kwargs) – Addi onal WPF a ributes

class [Link](name, default='', **kwargs)

[Link] Wrapper

>>> TextBox()

__init__(name, default='', **kwargs)

Parameters: name ( str ) – Name of control. Will be used to return value


default ( bool ) – Sets Text a ribute of textbox [Default: ‘’]
wpf_params (kwargs) – Addi onal WPF a ributes

class [Link](name, checkbox_text, default=False, **kwargs)

[Link] Wrapper

>>> CheckBox('Label')

__init__(name, checkbox_text, default=False, **kwargs)

Parameters: name ( str ) – Name of control. Will be used to return value


checkbox_text ( str ) – Checkbox label Text
default ( bool ) – Sets IsChecked state [Default: False]
wpf_params (kwargs) – Addi onal WPF a ributes

class [Link](name, op ons, default=None, sort=True, **kwargs)

[Link] Wrapper

>>> ComboBox({'Option 1': Element, 'Option 2', 'Elemnet'})


>>> ComboBox({'Option 1': Element, 'Option 2', 'Elemnet'}, sort=False)

__init__(name, op ons, default=None, sort=True, **kwargs)

Parameters: name ( str ) – Name of control. Will be used to return value


op ons ( list , dict ) – If dict , selected value is returned
default ( str ) – Sets SelectedItem a ribute [Default: first]
wpf_params (kwargs) – Addi onal WPF a ributes

class [Link](bu on_text, on_click=None, **kwargs)

[Link] on Wrapper

>>> Button('Select')

__init__(bu on_text, on_click=None, **kwargs)

Parameters: bu on_text ( str ) – Bu on Text


on_click ( func ) – Registers Click event Func on [Default:
FlexForm.get_values ]
wpf_params (kwargs) – Addi onal WPF a ributes

class [Link](**kwargs)

WPF Separator

Implementations
FlexForm

from itertools import count

from [Link] import Enum


from [Link] import *

class FlexForm(Window):
"""
Flex Form Usage

>>> from [Link] import (FlexForm, Label, ComboBox, TextBox, TextBox,


... Separator, Button, CheckBox)
>>> components = [Label('Pick Style:'),
... ComboBox('combobox1', {'Opt 1': 10.0, 'Opt 2': 20.0}),
... Label('Enter Name:'),
... TextBox('textbox1', Text="Default Value"),
... CheckBox('checkbox1', 'Check this'),
... Separator(),
... Button('Select')]
>>> form = FlexForm('Title', components)
>>> [Link]()
>>> # User selects `Opt 1`, types 'Wood' in TextBox, and select Checkbox
>>> [Link]
{'combobox1': 10.0, 'textbox1': 'Wood', 'checkbox': True}

"""
layout = """
<Window
xmlns="[Link]
xmlns:x="[Link]
xmlns:d="[Link]
xmlns:mc="[Link]
xmlns:local="clr-namespace:WpfApplication1" mc:Ignorable="d"
ResizeMode="NoResize"
WindowStartupLocation="CenterScreen"
Topmost="True"
SizeToContent="WidthAndHeight">

<Grid Name="MainGrid" Margin="10,10,10,10">


</Grid>
</Window>
"""

def __init__(self, title, components, **kwargs):


"""
Args:
title (``str``): Form Title
components (``list``): List of Form Components.
top_offset (``float``): Optional top offset.
options (``kwargs``): WPF Parameters Options

Attributes:
values (``dict``): Dictionary of selected values
"""

[Link] = [Link](self, StringReader([Link]))


[Link] = title
[Link] = {}

for key, value in [Link]():


setattr(self, key, value)

for n, component in enumerate(components):


[Link](component)
if hasattr(component, 'on_click'):
[Link] += component.on_click

V_SPACE = 5
if n > 0:
prev_comp = components[n - 1]
top = prev_comp.[Link] + prev_comp.Height + V_SPACE
top += getattr(component, 'top_offset', 0)
[Link] = Thickness(0, top, 0, 0)

def show(self):
"""
Initializes Form. Returns ``True`` or ``False`` if form was exited.
"""
return [Link]()

@staticmethod
def get_values(sender, e):
"""
Default Get Values. Set [Link] attribute with values from controls
and closes form.
"""
component_values = {}
window = [Link](sender)
for component in [Link]:
try:
component_values[[Link]] = [Link]
except AttributeError:
pass
[Link] = component_values
[Link]()

def close(self):
""" Exits Form. Returns ``True`` to ``show()`` method """
[Link] = True
[Link]()

class RpwControlMixin():
""" Control Mixin """
_index = count(0)

def __init__(self, **kwargs):


self.set_attrs(**kwargs)

def set_attrs(self, **kwargs):


""" Parses kwargs, sets default values where appropriate. """
[Link] = next(self._index) # Counts Instatiation to control Height

# Default Values
control_type = self.__class__.__name__
if not [Link]:
[Link] = [Link]('Name', '{}_{}'.format(control_type, [Link]))

[Link] = [Link]('Width', 300)


[Link] = [Link]('Height', 25)

h_align = [Link](HorizontalAlignment, [Link]('h_align', 'Left'))


[Link] = h_align
v_align = [Link](VerticalAlignment, [Link]('v_align', 'Top'))
[Link] = v_align

# Inject Any other Custom Values into Component


# Updating __dict__ fails due to how .NET inheritance/properties works
for key, value in [Link]():
setattr(self, key, value)

class Label(RpwControlMixin, [Link]):


"""
[Link] Wrapper

>>> Label('Label Text')


"""
def __init__(self, label_text, **kwargs):
"""
Args:
label_text (``str``): Label Text
wpf_params (kwargs): Additional WPF attributes
"""
[Link] = label_text
self.set_attrs(**kwargs)

class TextBox(RpwControlMixin, [Link]):


"""
[Link] Wrapper

>>> TextBox()
"""
def __init__(self, name, default='', **kwargs):
"""
Args:
name (``str``): Name of control. Will be used to return value
default (``bool``): Sets ``Text`` attribute of textbox [Default: '']
wpf_params (kwargs): Additional WPF attributes
"""
[Link] = name
[Link] = default
self.set_attrs(**kwargs)
if 'Height' not in kwargs:
[Link] = 25

@property
def value(self):
return [Link]

class Button(RpwControlMixin, [Link]):


"""
[Link] Wrapper

>>> Button('Select')
"""
def __init__(self, button_text, on_click=None, **kwargs):
"""
Args:
button_text (``str``): Button Text
on_click (``func``): Registers Click event Function [Default: :any:`FlexForm.get_values`]
wpf_params (kwargs): Additional WPF attributes
"""
[Link] = button_text
self.on_click = on_click or FlexForm.get_values
self.set_attrs(**kwargs)

class CheckBox(RpwControlMixin, [Link]):


"""
[Link] Wrapper

>>> CheckBox('Label')
"""
def __init__(self, name, checkbox_text, default=False, **kwargs):
"""
Args:
name (``str``): Name of control. Will be used to return value
checkbox_text (``str``): Checkbox label Text
default (``bool``): Sets IsChecked state [Default: False]
wpf_params (kwargs): Additional WPF attributes
"""
[Link] = name
[Link] = checkbox_text
[Link] = default
self.set_attrs(top_offset=5, **kwargs)

@property
def value(self):
return [Link]

class ComboBox(RpwControlMixin, [Link]):


"""
[Link] Wrapper

>>> ComboBox({'Option 1': Element, 'Option 2', 'Elemnet'})


>>> ComboBox({'Option 1': Element, 'Option 2', 'Elemnet'}, sort=False)
"""
def __init__(self, name, options, default=None, sort=True, **kwargs):
"""
Args:
name (``str``): Name of control. Will be used to return value
options (``list``, ``dict``): If ``dict``, selected value is returned
default (``str``): Sets SelectedItem attribute [Default: first]
wpf_params (kwargs): Additional WPF attributes
"""
[Link] = name
self.set_attrs(**kwargs)
index = 0

[Link] = options
if hasattr(options, 'keys'):
options = [Link]()
if sort:
[Link]()
if default is None:
index = 0
else:
index = [Link](default)

[Link]()
[Link] = options
[Link] = options[index]

@property
def value(self):
selected = [Link]
if isinstance([Link], dict):
selected = [Link][selected]
return selected

class Separator(RpwControlMixin, [Link]):


""" WPF Separator """

if __name__ == '__main__':
""" TESTS """
components = [
Label('Pick Style:'),
ComboBox('combobox1', {'Opt 1': 10.0, 'Opt 2': 20.0}),
Label('Enter Name:'),
TextBox('textbox1', Text="Default Value"),
CheckBox('checkbox1', 'Check this:'),
Separator(),
Button('Select')]

form = FlexForm('Title', components)


[Link]()

print([Link])

QuickForm

import sys

from [Link] import FlexForm, Label, ComboBox, TextBox, Button

def SelectFromList(title, options, description=None, sort=True, exit_on_close=True):


""" Simple FlexForm wrapped function with ComboBox and button

Args:
title (str): Title of form
options (dict,list[str]): Dictionary (string keys) or List[strings]
description (str): Optional Description of input requested [default: None]
sort (bool): Optional sort flag - sorts keys [default: True]
exit_on_close (bool): Form will call [Link]() if Closed on X. [default: True]

Usage:

>>> from [Link] import SelectFromList


>>> value = SelectFromList('Test Window', ['1','2','3'])
>>> # Dropdown shows '1', '2' ,'3'. User clicks Select '1'
>>> print(value)
'1'
>>> # Dictionary
>>> value = SelectFromList('Test Window', {'Text':str, 'Number':int})
>>> # User clicks Text
>>> print(value)
str
"""
components = []
if description:
[Link](Label(description))
[Link](ComboBox('combobox', options, sort=sort))
[Link](Button('Select'))
form = FlexForm(title, components)
ok = [Link]()
if ok:
return [Link]['combobox']
if exit_on_close:
[Link]()

def TextInput(title, default=None, description=None, sort=True, exit_on_close=True):


""" Simple FlexForm wrapped function with TextBox and button

Args:
title (str): Title of form
default (str): Optional default value for text box [default: None]
description (str): Optional Description of input requested [default: None]
exit_on_close (bool): Form will call [Link]() if Closed on X. [default: True]

Usage:

>>> from [Link] import TextInput


>>> value = TextInput('Title', default="3")
>>> print(value)
3
"""
components = []
if description:
[Link](Label(description))
if default:
textbox = TextBox('textbox', default=default)
else:
textbox = TextBox('textbox')
[Link](textbox)
[Link](Button('Select'))
form = FlexForm(title, components)
ok = [Link]()
if ok:
return [Link]['textbox']
if exit_on_close:
[Link]()

if __name__ == '__main__':
rv = SelectFromList('Title', ['A','B'], description="Your Options",
exit_on_close=True)
print(rv)

rv = SelectFromList('Title', {'A':5, 'B':10}, description="Your Options",


exit_on_close=True)
print(rv)

rv = TextInput('Title', default="3", exit_on_close=True)


print(rv)
print('[Link] ran')

TaskDialog

import sys
from rpw import UI
from [Link] import RpwValueError
from [Link] import BaseObjectWrapper, BaseObject

class Alert():
"""
A Simple Revit TaskDialog for displaying quick messages

Usage:
>>> from [Link] import Alert
>>> Alert('Your Message', title="Title", header="Header Text")
>>> Alert('You need to select Something', exit=True)

Args:
message (str): TaskDialog Content
title (str, optional): TaskDialog Title
header (str, optional): TaskDialog content header
exit (bool, optional): Exit Script after Dialog.
Useful for displayin Errors. Default is False

"""
def __init__(self, content, title='Alert', header='', exit=False):
dialog = [Link](title)
[Link] = False
[Link] = header
[Link] = content
[Link] = [Link]()

if exit:
[Link](1)

class CommandLink(BaseObject):
"""
Command Link Helper Class

Usage:
>>> from [Link] import CommandLink, TaskDialog
>>> CommandLink('Open Dialog', return_value=func_to_open)
>>> TaskDialog('Title', commands=[CommandLink])

Args:
text (str): Command Text
subtext (str, optional): Button Subtext
return_value (any, optional): Value returned if button is clicked.
If none is provided, text is returned.

"""
def __init__(self, text, subtext='', return_value=None):
self._id = None # This will later be set to TaskDialogCommandLinkId(n)
[Link] = text
[Link] = subtext
self.return_value = return_value if return_value is not None else text

def __repr__(self):
return super(CommandLink, self).__repr__(data={'id': self._id,
'text':[Link]})

class TaskDialog(BaseObjectWrapper):
"""
Task Dialog Wrapper

>>> from [Link] import CommandLink, TaskDialog


>>> commands= [CommandLink('Open Dialog', return_value='Open'),
>>> ... CommandLink('Command', return_value=lambda: True)]
>>> ...
>>> dialog = TaskDialog('This TaskDialog has Buttons ',
>>> ... title_prefix=False,
>>> ... content="Further Instructions",
>>> ... commands=commands,
>>> ... buttons=['Cancel', 'OK', 'RETRY'],
>>> ... footer='It has a footer',
>>> ... # verification_text='Add Verification Checkbox',
>>> ... # expanded_content='Add Expanded Content',
>>> ... show_close=True)
>>> [Link]()
'Open'

Wrapped Element:
self._revit_object = `[Link]`

Args:
content (str): Main text of TaskDialog.
commands (list, optional): List of CommandLink Instances.
Default is no buttons.
buttons (list, optional): List of TaskDialogCommonButtons names.
Default is no buttons. 'Close' is shown if no commands are passed.
title (str, optional): Title of TaskDialog. Default is 'Task Dialog'.p
instruction (str, optional): Main Instruction.
footer (str, optional): Footer Text. Default is ``blank``.
expanded_content (str, optional): Expandable Text. Default is ``blank``.
verification_text (str, optional): Checkbox text. Default is ``blank``.
title_prefix (bool, optional): Prefix Title with app name.
Default is ``False``
show_close (bool, optional): Show X to close. Default is False.

"""
_revit_object_class = [Link]
_common_buttons = ['Ok', 'Yes', 'No', 'Cancel', 'Retry', 'Close']

def __init__(self, instruction, commands=None, buttons=None,


title='Task Dialog', content='',
title_prefix=False, show_close=False,
footer='', expanded_content='', verification_text=''
):

super(TaskDialog, self).__init__([Link](title))
[Link] = self._revit_object

# Settings
[Link] = title_prefix
[Link] = show_close

# Properties
[Link] = title
[Link] = instruction
[Link] = content
[Link] = footer
[Link] = expanded_content
[Link] = verification_text
self.verification_checked = None if not verification_text else False

# Add Buttons
[Link] = buttons or []
common_buttons_names = []
for button_name in [[Link]() for b in [Link]]:
if button_name not in self._common_buttons:
raise RpwValueError('TaskDialogCommonButtons member', button_name)
button_full_name = '[Link].' + button_name
common_buttons_names.append(button_full_name)

if common_buttons_names:
common_buttons = eval('|'.join(common_buttons_names))
[Link] = common_buttons

# Set Default Button


[Link] = [Link]

# Validate Commands
commands = commands or []
if len(commands) > 4:
raise RpwValueError('4 or less command links', len(commands))

# Process Commands
[Link] = {}
for link_index, command_link in enumerate(commands, 1):
command_id = 'CommandLink{}'.format(link_index)
command_link._id = getattr([Link], command_id)
[Link][command_id] = command_link
[Link](command_link._id,
command_link.text,
command_link.subtext)

def show(self, exit=False):


"""
Show TaskDialog

Args:
exit (bool, optional): Exit Script after Dialog. Useful for
displaying Errors. Default is False.

Returns:
Returns is ``False`` if dialog is Cancelled (X or Cancel button).
If CommandLink button is clicked, ``CommandLink.return_value``
is returned - if one was not provided, ``[Link]`` is used.
If CommonButtons are clicked ``[Link]`` name is
returned ie('Close', 'Retry', 'Yes', etc).
"""
[Link] = [Link]()

try:
self.verification_checked = [Link]()
except:
self.verification_checked = None

# Handle Cancel
if [Link] == [Link]:
if exit:
[Link](1)
return None

# If result is a CommandLink, return Return Value else Result


command_link = [Link](str([Link]))
if command_link:
return command_link.return_value
else:
return [Link]()

if __name__ == '__main__':
Alert('Test Alert!')

def sample_callback():
print('Calling B')
d = [Link]("Revit Build Information")
[Link] = "Button 1"
[Link]()

from [Link] import *


commands = [
CommandLink('TestTitle', return_value=sample_callback, subtext='test subtext'),
CommandLink('TestTitle2', return_value=lambda: 'Empty', subtext='test subtext2')
]

t = TaskDialog(commands=commands, buttons=['Yes'])

OS Dialogs

from [Link] import *

def select_folder():
"""
Selects a Folder Path using the standard OS Dialog.
Uses [Link](). For more information see:
[Link]

>>> from [Link] import select_folder


>>> folderpath = select_folder()
'C:\\folder\\path'
"""

form = [Link]()
if [Link]() == [Link]:
return [Link]

def select_file(extensions='All Files (*.*)|*.*',


title="Select File",
multiple=False,
restore_directory=True):
"""
Selects a File Path using the standard OS Dialog.
Uses [Link]
[Link]

>>> from [Link] import select_file


>>> filepath = select_file('Revit Model (*.rvt)|*.rvt')
'C:\\folder\\[Link]'

Args:
extensions (str, optional): File Extensions Filtering options. Default is All Files (*.*)|*.*
title (str, optional): File Extensions Filtering options
multiple (bool): Allow selection of multiple files. Default is `False`
restore_directory (bool): Restores the directory to the previously selected directory before clo

Returns:
filepath (list, string): filepath string if ``multiple=False`` otherwise list of filepath string

"""
form = [Link]()
[Link] = extensions
[Link] = title
[Link] = multiple
[Link] = restore_directory
if [Link]() == [Link]:
return [Link] if not multiple else list([Link])

# Tests
if __name__ == '__main__':
# print(select_folder())
# print(select_file('Python Files|*.py'))
print(select_file('Python Files|*.py', multiple=False))
print(select_file('Python Files|*.py', multiple=True))

Console

import os
import inspect
import logging
import tempfile
from collections import defaultdict
import traceback

from [Link] import Completer


from [Link] import Window
from [Link] import *
# [Link](False)

class Console(Window):
LAYOUT = """
<Window xmlns="[Link]
xmlns:x="[Link]
Title="DeployWindow" Height="400" Width="800" SnapsToDevicePixels="True"
UseLayoutRounding="True" WindowState="Normal"
WindowStartupLocation="CenterScreen">
<[Link]>
<Style TargetType="{x:Type MenuItem}">
<Setter Property="FontFamily" Value="Consolas"/>
<Setter Property="FontSize" Value="12.0"/>
</Style>
</[Link]>
<Grid>
<[Link]>
<ColumnDefinition Width="*"></ColumnDefinition>
</[Link]>
<[Link]>
<RowDefinition Height="0"></RowDefinition>
<RowDefinition Height="*"></RowDefinition>
</[Link]>
<TextBox [Link]="1" [Link]="1" HorizontalAlignment="Stretch"
Name="tbox" Margin="6,6,6,6" VerticalAlignment="Stretch"
AcceptsReturn="True" VerticalScrollBarVisibility="Auto"
TextWrapping="Wrap"
FontFamily="Consolas" FontSize="12.0"
/>
</Grid>
</Window>
"""
# <Button Content="Terminate" Margin="6,6,6,6" Height="30"
# [Link]="1" [Link]="1" VerticalAlignment="Bottom"
# Click="terminate"></Button>

CARET = '>>> '

def __init__(self, stack_level=1, stack_info=True, context=None, msg=''):


"""
Args:
stack_level (int): Default is 1. 0 Is the Console stack, 1 is the
caller; 2 is previous to that, etc.
stack_info (bool): Display info about where call came from.
Will print filename name, line no. and Caller
name.
msg (str): Message to display on start.
Only available if using context
context (dict): Optional Dictionary for when inspection is not
possible.
"""

# History Helper
tempdir = [Link]()
filename = 'rpw-history'
self.history_file = [Link](tempdir, filename)

self.stack_locals = {}
self.stack_globals = {}
self.stack_level = stack_level

if context:
self.stack_locals.update(context)
# Allows to pass context manually, so it can be used in Dynamo
# Where inspection does not work
else:
# Stack Info
# stack_frame = [Link]().f_back
stack_frame = [Link]()[stack_level][0] # Finds Calling Stack

self.stack_locals.update(stack_frame.f_locals)
self.stack_globals.update(stack_frame.f_globals)
# Debug Console
self.stack_globals.update({'stack': [Link]()})

stack_code = stack_frame.f_code
stack_filename = [Link](stack_code.co_filename)
stack_lineno = stack_code.co_firstlineno
stack_caller = stack_code.co_name

self._update_completer()

# Form Setup
[Link] = [Link](self, StringReader([Link]))
[Link] = 'RevitPythonWrapper Console'
[Link] += [Link]
[Link] += [Link]
self.is_loaded = False

# Form Init
[Link]()
if not context and stack_info:
self.write_line('Caller: {} [ Line:{}] | File: {}'.format(
stack_caller,
stack_lineno,
stack_filename))
elif msg:
self.write_line(msg)
else:
[Link] = [Link]

[Link] = len([Link])

# Vars
self.history_index = 0
self.ac_options = defaultdict(int)

[Link]()

def force_quit(self, sender, e):


raise SystemExit('Force Quit')

def _update_completer(self):
# Updates Completer. Used at start, and after each exec loop
context = self.stack_locals.copy()
[Link](self.stack_globals)
# [Link](vars(__builtins__))
[Link] = Completer(context)

def get_line(self, index):


line = [Link](index).replace('\r\n', '')
if [Link]([Link]):
line = line[len([Link]):]
[Link]('Get Line: {}'.format(line))
return line

def get_last_line(self):
try:
last_line = self.get_lines()[-1]
except IndexError:
last_line = self.get_line(0)
[Link]('Last Line: {}'.format(last_line))
return last_line

def get_last_entered_line(self):
try:
last_line = self.get_lines()[-2]
except IndexError:
last_line = self.get_line(0)
[Link]('Last Line: {}'.format(last_line))
return last_line

def get_lines(self):
last_line_index = [Link]
lines = []
for index in range(0, last_line_index):
line = self.get_line(index)
[Link](line)
[Link]('Lines: {}'.format(lines))
return lines

def OnKeyUpHandler(self, sender, args):


# Need to use this to be able to override ENTER
if not self.is_loaded:
return
if [Link] == [Link]:
entered_line = self.get_last_entered_line()
if entered_line == '':
self.write_line(None)
return
output = [Link](entered_line)
self.append_history(entered_line)
self.history_index = 0
self.write_line(output)
[Link]()

def format_exception(self):
""" Formats Last Exception"""
exc_type, exc_value, exc_traceback = sys.exc_info()
tb = traceback.format_exception(exc_type, exc_value, exc_traceback)
last_exception = tb[-1]
output = 'Traceback:\n' + last_exception[:-1]
return output

def evaluate(self, line):


try:
output = eval(line, self.stack_globals, self.stack_locals)
except SyntaxError as exc:
try:
exec(line, self.stack_globals, self.stack_locals)
self._update_completer() # Update completer with new locals
return
except Exception as exc:
output = self.format_exception()
except Exception as exc:
output = self.format_exception()
return str(output)

def OnKeyDownHandler(self, sender, args):


pass

@property
def last_caret_start_index(self):
return [Link]([Link])

@property
def last_caret_end_index(self):
return self.last_caret_start_index + len([Link])

@property
def last_caret_line_start_index(self):
return self.last_caret_start_index - len([Link])

def reset_caret(self):
[Link] = self.last_caret_end_index

def KeyPressPreview(self, sender, e):


# This Happens before all other key handlers
# If [Link] = True, stops event propagation here.
[Link] = False
if [Link] < self.last_caret_start_index:
[Link] = len([Link])
if [Link] == [Link]:
self.history_up()
[Link] = True
if [Link] == [Link]:
self.history_down()
[Link] = True
if [Link] == [Link] or [Link] == [Link]:
if [Link] == self.last_caret_end_index:
[Link] = True
if [Link] == [Link]:
self.reset_caret()
[Link] = True
if [Link] == [Link]:
[Link]()
[Link] = True
if [Link] == [Link]:
self.is_loaded = True
[Link] = len([Link])

def autocomplete(self):
text = [Link][self.last_caret_end_index:[Link]]
[Link]('Text: {}'.format(text))

# Create Dictionary to Track iteration over suggestion


index = self.ac_options[text]
suggestion = [Link](text, index)

[Link]('ac_options: {}'.format(self.ac_options))
[Link]('Sug: {}'.format(suggestion))

if not suggestion:
self.ac_options[text] = 0
else:
self.ac_options[text] += 1
if [Link]('('):
suggestion = suggestion[:-1]

if suggestion is not None:


caret_index = [Link]
self.write_text(suggestion)
[Link] = caret_index

def write(self, text):


""" Make Console usable as File Object """
self.write_line(line=text)

def write_line(self, line=None):


# Used for Code Output
# Writes line with no starting caret, new line + caret
if line:
[Link](line)
[Link](NewLine)
[Link]([Link])

def write_text(self, line):


# Used by Autocomplete and History
# Adds text to line, including Caret
[Link] = [Link][0:self.last_caret_start_index]
[Link]([Link])
[Link](line)
[Link] = len([Link])

def get_all_history(self):
# TODO: Add clean up when history > X
with open(self.history_file) as fp:
lines = [Link]().split('\n')
return [line for line in lines if line != '']

def history_up(self):
self.history_index += 1
line = self.history_iter()
if line is not None:
self.write_text(line)

def history_down(self):
self.history_index -= 1
line = self.history_iter()
if line is not None:
self.write_text(line)

def append_history(self, line):


[Link]('Adding Line to History:' + repr(line))
with open(self.history_file, 'a') as fp:
[Link](line + '\n')

def history_iter(self):
lines = self.get_all_history()
[Link]('Lines: {}'.format(lines))
try:
line = lines[::-1][self.history_index - 1]
# Wrap around lines to loop and up down infinetly.
except IndexError:
if len(lines) == 0:
return None
if len(lines) < 0:
self.history_index += len(lines)
if len(lines) > 0:
self.history_index -= len(lines)
line = lines[0]
return line

def __repr__(self):
'<rpw:Console stack_level={}>'.format(self.stack_level)

if __name__ == '__main__':
def test():
x = 1
# Console()
Console(context=locals())
test()
z = 2

Resources

import sys

from abc import ABCMeta

from rpw import revit


from [Link] import clr
from [Link] import logger

# WPF/Form Imports
[Link]("PresentationFramework") # [Link]: Controls, ?
[Link]("WindowsBase") # [Link]
[Link]("[Link]") # FontFamily
[Link]('[Link]') # Forms

import [Link]
from [Link] import Window
from [Link] import StringReader

# Console
from [Link] import Exit, NewLine
from [Link] import FontFamily
from [Link] import Key

# FlexForm Imports
from [Link] import Controls, Window
from [Link] import HorizontalAlignment, VerticalAlignment, Thickness

# OS Dialogs
from [Link] import Forms

if [Link] == 'Dynamo':
# IronPython 2.7.3 - Dynamo + RPS w/out pyRevit
# Conflicts with PyRevit. Must Ensure exact path is specified
# [Link]
[Link](r'C:\Program Files (x86)\IronPython 2.7\Platforms\Net40\[Link]
import wpf
# on 2.7.7 this raises wpf import error
else:
# IronPython 2.7.7 - pyRevit
# [Link]('IronPython') # Works W/Out
[Link]('[Link]') # 2.7.
from [Link] import Wpf as wpf
# on 2.7.7 this works. On 2.7.3 you get a LoadComponent 3 args error

 Previous Next 

Love Documentation? Write the Docs is for


people like you! Join our virtual conferences
or Slack.

Community Ad

© Copyright 2017, Gui Talarico Revision 50d96adf.

Built with Sphinx using a theme provided by Read the Docs.

You might also like