Skip to content

settings_window

Dynamic Settings Window for pyRevit Creates a reusable WPF window for managing script configurations.

Usage

from pyrevit import script from pyrevit.forms import settings_window

settings = [ {"type": "section", "label": "Display"}, {"name": "scope", "type": "choice", "label": "Scope", "options": ["Visibility", "Active State"], "default": "Visibility"}, {"name": "highlight_color", "type": "color", "label": "Highlight Color", "default": "#ffff0000"},

{"type": "section", "label": "Processing"},
{"name": "set_workset", "type": "bool", "label": "Set Workset", "default": True},
{"name": "tolerance", "type": "slider", "label": "Tolerance (mm)",
 "default": 10, "min": 0, "max": 1000},
{"name": "prefix", "type": "string", "label": "Prefix", "default": ""},

{"type": "section", "label": "Paths"},
{"name": "export_folder", "type": "folder", "label": "Export Folder", "default": ""},
{"name": "template_file", "type": "file", "label": "Template File",
 "default": "", "file_ext": "rvt", "files_filter": "Revit Files (*.rvt)|*.rvt"},

]

if settings_window.show_settings(settings, title="My Tool Settings"): print("Settings saved!")

Classes

SettingsWindow(settings_schema, section=None, title='Settings', width=450)

Bases: WPFWindow

Dynamic settings window that generates UI from schema.

Initialize the settings window.

Parameters:

Name Type Description Default
settings_schema

List of setting definitions

required
section

Config section name

None
title

Window title

'Settings'
width

Window width in pixels

450
Source code in pyrevitlib/pyrevit/forms/settings_window.py
def __init__(
    self, settings_schema, section=None, title="Settings", width=450,
):
    """Initialize the settings window.

    Args:
        settings_schema: List of setting definitions
        section: Config section name
        title: Window title
        width: Window width in pixels
    """
    self.config = script.get_config(section)
    self.settings_schema = settings_schema
    self.window_title = title
    self.window_width = width
    self.config_section = section
    self.result = False
    self.controls = {}

    xaml_string = self._generate_xaml()
    forms.WPFWindow.__init__(self, xaml_string, literal_string=True)

    self.Title = self.window_title
    self._populate_values()

    self.save_button.Click += self.save_clicked
    self.cancel_button.Click += self.cancel_clicked
    self.reset_button.Click += self.reset_clicked

Attributes

config = script.get_config(section) instance-attribute
settings_schema = settings_schema instance-attribute
window_title = title instance-attribute
window_width = width instance-attribute
config_section = section instance-attribute
result = False instance-attribute
controls = {} instance-attribute
Title = self.window_title instance-attribute

Functions

save_clicked(sender, args)

Handle save button click.

Source code in pyrevitlib/pyrevit/forms/settings_window.py
def save_clicked(self, sender, args):
    """Handle save button click."""
    errors = []
    validated_values = {}

    for setting in self.settings_schema:
        setting_type = setting.get("type", "string")

        # Skip display-only items — no value to read.
        if setting_type in _DISPLAY_ONLY_TYPES:
            continue

        name = setting.get("name")
        control = self.controls.get(name)
        if not control:
            continue

        # Read value from control according to its type.
        if setting_type == "bool":
            value = control.IsChecked
        elif setting_type == "choice":
            value = control.SelectedItem
        elif setting_type == "slider":
            value = control.Value  # float from WPF Slider
        else:
            value = control.Text

        is_valid, validated_value, error_msg = self._validate_setting(
            setting, value
        )

        if not is_valid:
            errors.append(error_msg)
        else:
            validated_values[name] = validated_value

    if errors:
        forms.alert("\n".join(errors), title="Validation Error", warn_icon=True)
        return

    for setting in self.settings_schema:
        name = setting.get("name")
        if name in validated_values:
            self.config.set_option(name, validated_values[name])

    script.save_config()
    self.result = True
    self.Close()
cancel_clicked(sender, args)

Handle cancel button click.

Source code in pyrevitlib/pyrevit/forms/settings_window.py
def cancel_clicked(self, sender, args):
    """Handle cancel button click."""
    self.result = False
    self.Close()
reset_clicked(sender, args)

Handle reset button click.

Source code in pyrevitlib/pyrevit/forms/settings_window.py
def reset_clicked(self, sender, args):
    """Handle reset button click."""
    if forms.alert(
        "Are you sure you want to reset all settings, removing it from the .ini?",
        title="Reset Settings",
        yes=True,
        no=True,
    ):
        script.reset_config(self.config_section)
        self.result = False
        self.Close()

Functions

show_settings(settings_schema, section=None, title='Settings', width=450)

Show settings window and return True if saved.

Parameters:

Name Type Description Default
settings_schema

List of setting definitions. Each entry is a dict with:

Structural / display-only (no "name" key required): - type "section" -- bold heading + separator line. Requires "label". - type "separator" -- bare horizontal rule, no label.

Interactive settings (all require "name"): - type "bool" -- CheckBox. - type "choice" -- ComboBox. Requires "options" list. - type "slider" -- Slider with live readout. Supports "min", "max", "step". - type "int" -- TextBox validated as integer. Supports "min", "max". - type "float" -- TextBox validated as float. Supports "min", "max". - type "string" -- TextBox. Supports "required" (bool). - type "color" -- TextBox + color-preview swatch + picker button. - type "folder" -- TextBox + folder-browse button. - type "file" -- TextBox + file-browse button. Supports "file_ext", "files_filter", "init_dir", "multi_file".

Common optional keys for interactive settings: - name (str): Setting key stored in .ini config. - label (str): Human-readable label shown in the UI. - default: Value used when no config entry exists yet. - required (bool): For "string" / path types — blocks save if empty.

required
section str

Config section name (default: None)

None
title str

Window title (default: "Settings")

'Settings'
width int

Window width in pixels (default: 450)

450

Returns:

Name Type Description
bool

True if settings were saved, False if canceled/reset.

Example::

settings_schema = [
    {"type": "section", "label": "Display"},
    {"name": "scope", "type": "choice", "label": "Scope",
     "options": ["Visibility", "Active State"], "default": "Visibility"},
    {"name": "highlight_color", "type": "color", "label": "Highlight Color",
     "default": "#ffff0000"},

    {"type": "section", "label": "Processing"},
    {"name": "tolerance", "type": "slider", "label": "Tolerance (mm)",
     "default": 10, "min": 0, "max": 1000, "step": 5},
    {"name": "set_workset", "type": "bool", "label": "Set Workset",
     "default": True},

    {"type": "separator"},

    {"name": "prefix", "type": "string", "label": "Prefix", "default": ""},
]

if show_settings(settings_schema, section="MyToolSection", title="My Tool Settings"):
    print("Settings saved!")
Source code in pyrevitlib/pyrevit/forms/settings_window.py
def show_settings(settings_schema, section=None, title="Settings", width=450):
    """Show settings window and return True if saved.

    Args:
        settings_schema: List of setting definitions. Each entry is a dict with:

            Structural / display-only (no "name" key required):
            - type "section"   -- bold heading + separator line.  Requires "label".
            - type "separator" -- bare horizontal rule, no label.

            Interactive settings (all require "name"):
            - type "bool"      -- CheckBox.
            - type "choice"    -- ComboBox. Requires "options" list.
            - type "slider"    -- Slider with live readout. Supports "min", "max", "step".
            - type "int"       -- TextBox validated as integer. Supports "min", "max".
            - type "float"     -- TextBox validated as float.  Supports "min", "max".
            - type "string"    -- TextBox. Supports "required" (bool).
            - type "color"     -- TextBox + color-preview swatch + picker button.
            - type "folder"    -- TextBox + folder-browse button.
            - type "file"      -- TextBox + file-browse button.
                                  Supports "file_ext", "files_filter", "init_dir",
                                  "multi_file".

            Common optional keys for interactive settings:
            - name (str):     Setting key stored in .ini config.
            - label (str):    Human-readable label shown in the UI.
            - default:        Value used when no config entry exists yet.
            - required (bool): For "string" / path types — blocks save if empty.

        section (str): Config section name (default: None)
        title (str):   Window title (default: "Settings")
        width (int):   Window width in pixels (default: 450)

    Returns:
        bool: True if settings were saved, False if canceled/reset.

    Example::

        settings_schema = [
            {"type": "section", "label": "Display"},
            {"name": "scope", "type": "choice", "label": "Scope",
             "options": ["Visibility", "Active State"], "default": "Visibility"},
            {"name": "highlight_color", "type": "color", "label": "Highlight Color",
             "default": "#ffff0000"},

            {"type": "section", "label": "Processing"},
            {"name": "tolerance", "type": "slider", "label": "Tolerance (mm)",
             "default": 10, "min": 0, "max": 1000, "step": 5},
            {"name": "set_workset", "type": "bool", "label": "Set Workset",
             "default": True},

            {"type": "separator"},

            {"name": "prefix", "type": "string", "label": "Prefix", "default": ""},
        ]

        if show_settings(settings_schema, section="MyToolSection", title="My Tool Settings"):
            print("Settings saved!")
    """
    window = SettingsWindow(settings_schema, section, title, width)
    window.ShowDialog()
    return window.result