Custom UI Dialog
By adding UI configuration in the script header, you can create graphical parameter input dialogs to make scripts more user-friendly.
UI Configuration Format
Two formats are supported:
Format 1: Single-line Comment Format
# UI: {"fields":[field1, field2, ...]}
Suitable for simple configurations with few fields.
Example:
# UI: {"fields":[{"name":"count","field_type":"number","label":"Count:","default_value":"10","options":[]}]}
Format 2: Triple-quoted String Format (Recommended)
Single line:
"""UI:{"fields":[field1, field2, ...]}"""
Multi-line (recommended for complex configurations):
"""UI:{
"fields": [
{
"name": "start_time",
"field_type": "number",
"label": "Start time (ms):",
"default_value": "0",
"options": []
},
{
"name": "operation",
"field_type": "select",
"label": "Operation type:",
"default_value": "cut",
"options": ["cut", "copy", "delete"]
}
]
}"""
Field Configuration
Each field is a JSON object containing the following properties:
{
"name": "parameter_name",
"field_type": "field_type",
"label": "display_label",
"default_value": "default_value",
"options": ["option1", "option2"]
}
Property Description
| Property | Description | Required |
|---|---|---|
name | Parameter variable name, used to get value in code | Yes |
field_type | Field type (see table below) | Yes |
label | Label text displayed in UI | Yes |
default_value | Default value (string format) | Yes |
options | Option list for dropdown (only for select type) | No |
Supported Field Types
| Type | UI Control | Description | Example Default |
|---|---|---|---|
text | Text input | Single line text input | "Hello" |
number | Number input | Number input with hints | "100" |
bool | Checkbox | Boolean value selection | "true" or "false" |
select | Dropdown | Select from predefined options | "option1" |
Notes:
selecttype must provideoptionsarray- All
default_valueare in string format booltype values are"true"or"false"(strings)
Parameter Retrieval
When using custom UI, parameters are passed as a JSON string:
import sys
import json
def main():
if len(sys.argv) < 2:
print("Error: No parameters provided")
return
try:
# Parse JSON parameters from custom UI
params = json.loads(sys.argv[1])
# Get parameter values
start_time = float(params.get('start_time', '0'))
end_time = float(params.get('end_time', '10000'))
keep_notes = params.get('keep_notes', 'true') == 'true'
operation = params.get('operation', 'cut')
print(f"Start time: {start_time}")
print(f"End time: {end_time}")
print(f"Keep notes: {keep_notes}")
print(f"Operation type: {operation}")
except json.JSONDecodeError as e:
print(f"Error: Unable to parse parameters - {e}")
Key Points:
- All parameters are packed into one JSON string
- Retrieved via
sys.argv[1] - Parse using
json.loads() - Parameter values are all strings, need manual type conversion
Complete Examples
Example 1: Multiple Field Types
# Description: Process track notes in chart
"""UI:{
"fields": [
{
"name": "start_time",
"field_type": "number",
"label": "Start time (ms):",
"default_value": "0",
"options": []
},
{
"name": "end_time",
"field_type": "number",
"label": "End time (ms):",
"default_value": "10000",
"options": []
},
{
"name": "keep_notes",
"field_type": "bool",
"label": "Keep notes in this range?",
"default_value": "true",
"options": []
},
{
"name": "operation",
"field_type": "select",
"label": "Operation type:",
"default_value": "cut",
"options": ["cut", "copy", "delete", "move"]
}
]
}"""
import sys
import json
from rct_api import get_current_chart, save_current_chart
def main():
if len(sys.argv) < 2:
print("Error: No parameters provided")
return
try:
params = json.loads(sys.argv[1])
start_time = float(params.get('start_time', '0'))
end_time = float(params.get('end_time', '10000'))
keep_notes = params.get('keep_notes', 'true') == 'true'
operation = params.get('operation', 'cut')
chart = get_current_chart()
if not chart:
print("Error: Unable to get chart")
return
# Processing logic
print(f"Executing {operation} operation: {start_time}ms - {end_time}ms")
if keep_notes:
chart.filter_notes_by_time(start_time, end_time)
else:
# Reverse filter logic...
pass
save_current_chart(chart)
print("Processing complete")
except json.JSONDecodeError as e:
print(f"Error: Unable to parse parameters - {e}")
except Exception as e:
print(f"Error: {e}")
if __name__ == "__main__":
main()
Example 2: Simple Single Field
# Description: Generate specified number of notes
# UI: {"fields":[{"name":"count","field_type":"number","label":"Note count:","default_value":"10","options":[]}]}
import sys
import json
from rct_api import get_current_chart, save_current_chart, Note
def main():
if len(sys.argv) < 2:
return
params = json.loads(sys.argv[1])
count = int(params.get('count', '10'))
chart = get_current_chart()
if not chart:
return
for i in range(count):
time = i * 1000
degree = (i * 45) % 360
chart.add_note(Note.TAP, time, degree)
chart.sort()
save_current_chart(chart)
print(f"Generated {count} notes")
if __name__ == "__main__":
main()
Example 3: Text Input
# Description: Search and mark notes at specific angles
"""UI:{
"fields": [
{
"name": "degree",
"field_type": "number",
"label": "Target angle:",
"default_value": "0",
"options": []
},
{
"name": "tolerance",
"field_type": "number",
"label": "Error range:",
"default_value": "5",
"options": []
},
{
"name": "comment",
"field_type": "text",
"label": "Comment:",
"default_value": "Marked",
"options": []
}
]
}"""
import sys
import json
from rct_api import get_current_chart
def main():
if len(sys.argv) < 2:
return
params = json.loads(sys.argv[1])
target_degree = float(params.get('degree', '0'))
tolerance = float(params.get('tolerance', '5'))
comment = params.get('comment', 'Marked')
chart = get_current_chart()
if not chart:
return
found_count = 0
for note in chart.notes:
if abs(note.degree - target_degree) <= tolerance:
found_count += 1
print(f"Found {found_count} notes at {target_degree}° (±{tolerance}°)")
print(f"Comment: {comment}")
if __name__ == "__main__":
main()