When learning configuration, you often want to try a formula or a few conditions before placing them in a button script. The Program page already provides three entries for this: Master Script, Second Script and MDI.
This lesson uses the existing function keys, input windows and note help. First follow the original UI and scripts: how text is saved, which interpreter executes it, and how parameter fields build the note tree. Then append one note to the existing category to learn how to extend its contents while keeping the original page and shared handlers.
Open Program. Sign in with developer permission as described in Function-key configuration, right-click the function key you want to configure, and select the required function.
Click the screenshot to view the original image.
Figure 1. A close-up of the original menu. These are the names used by the English interface.
For this lesson, assign Master Script to F4 and Second Script to F5, and use MDI at its original F7 position. F4 and F5 are example positions. Note their previous functions so you can select them again afterwards. If a function is already assigned elsewhere, check that existing button first.
Developer sign-in and menu visibility are separate conditions. The standard configuration also uses Enable developer permissions, corresponding to #929.item[6], to control whether the two developer script entries appear. If they remain absent after sign-in, check this configuration setting and the existing assignments. Use normal sign-in rather than changing the parameter that records the signed-in role.
Start with the purpose of each entry:
| Name in the function-key menu | Window title | What to try here |
|---|---|---|
| Master Script | Master Script Interpreter | Formulas, parameter handling and control operations for main-window configuration scripts |
| Second Script | Secondary Script Interpreter | Formulas, parameter handling and control operations for auxiliary-window configuration scripts |
| MDI | MDI | Assignments, loops, branches and NC commands in an NC program |
All three windows accept text, but they use different execution entries. When connecting finished code to a normal button, keep the entry appropriate to its purpose.
Click the Master Script function you have just assigned. Preserve any existing input, then enter these three lines. The example uses #100, #101, and #9999 for the displayed result.
#100=12
#101=8
#9999=#100*#101
Click Execute at the lower right. The bottom of the window shows Debugging information:96.
Click the screenshot to view the original image.
Read it one line at a time: prepare 12, prepare 8, then multiply them and put the result in the parameter used by this window's result label.
The result area does not list every variable automatically. It shows 96 because the last line explicitly assigns that value to #9999. To inspect another calculated parameter here, assign its value to #9999.
Now change only the 8 on the second line to 12:
#100=12
#101=12
#9999=#100*#101
Click Execute again. The result becomes Debugging information:144.
Click the screenshot to view the original image.
Each click runs the whole input file again. These first two lines assign their values again each time; the program does not keep multiplying the previous result.
Close the window and open it again from the same function key. The three lines remain, but the result is initially cleared. Click Execute again to obtain 144.
Two separate actions explain this:
#9999. This clears the displayed result, not the input file.The Master Script input file is env/mdi/mainParser. It is a text script even though it has no extension. The label above the input shows a path such as MDI:env/mdi/mainParser; the actual prefix depends on the current environment directory.
“MDI:” is shared file-label text in these windows. It does not identify the interpreter executing the input. Use the selected function, window title and Execute-button settings described below to distinguish them.
The input file is a working file that you can edit repeatedly. Save a useful finished function under a meaningful name; do not keep its only copy in this scratch area. The runtime directory also needs write permission for input to save correctly.
Open Second Script, enter the first three-line example for 12 × 8, and click Execute. The result is 96.
Click the screenshot to view the original image.
This window saves to env/mdi/auxParser. It does not overwrite the 12 × 12 code in the Master Script file. Each file retains its own input.
Master Script and Second Script both use configuration-script syntax. For operations that find a control by name, such as the PlainTextEdit operations in widgetFunc, one important difference is which window is searched:
| What the code does | What to check |
|---|---|
| Calculate formulas or read/write parameters | Check the meaning of the parameters. Separate input files do not create separate sets of system parameters. |
| Operate a control through Master Script | Look for the control in the main window. |
| Operate a control through Second Script | Look for the control in the current auxiliary window. |
| Move a control operation into another window | Check the destination window, control name and interpreter number in its button event again. |
For example, before using the name plainTextEdit, identify which window contains that input control. A name present in the auxiliary window may not exist in the main window.
Some macro functions also accept a parameter that selects a different target window. Follow that function's description; the names Master Script and Second Script alone do not determine every operation's target.
Second Script is not an automatic second step after Master Script. It has its own entry. Selecting it does not establish a sequence between two scripts, and it is not a switch that automatically moves a long loop into the background.
Now use MDI to calculate 1 + 2 + 3. Make sure the system is idle and reset has been released. Preserve any existing input, then enter:
#100=0
#101=0
WHILE#100<3DO1
#100=#100+1
#101=#101+#100
END1
#9999=#101
Click Execute. When the program completes, the bottom of the window shows Debugging information:6.
Click the screenshot to view the original image.
| Pass | #100 after adding 1 | Accumulated #101 |
|---|---|---|
| First | 1 | 1 |
| Second | 2 | 3 |
| Third | 3 | 6 |
Once #100 equals 3, #100<3 is false. The program leaves the loop and writes the final sum to #9999.
This input is saved to env/mdi/macroMDI1.nc and executed by the NC interpreter. The example contains only assignments and a loop. MDI can also execute actual NC actions. When adding G or M commands later, check the coordinates, speeds and machine conditions required by those commands.
Clicking Execute submits an NC execution request. The NC scheduler then processes it. Completion of the button action does not mean the NC program has finished. Reset prevents NC execution from proceeding; an occupied NC channel also prevents repeated submissions as though it were idle.
If MDI produces no result, check reset, busy status and error messages before examining the input. Repeated clicks or arbitrary delays do not resolve those operating conditions.
The useful design technique is to store each entry's contents in parameter fields and put the actions shared by all entries in scripts. New contents can use the existing tree and handlers; each note does not need its own button.
The design has three parts:
| Part | Implementation here | Responsibility |
|---|---|---|
| Contents | Parameters and items in the #9000–#9029 range |
Category names, statement fragments, short descriptions, detailed help and image paths |
| Page rules | Properties of the original treeWidget |
Select categories and entries, then specify the field displayed in each column |
| Shared actions | env/mdi/tiphelp and env/mdi/inserttip |
Show help on a single click; insert a fragment on a double-click |
Follow the existing B-class macro program statement → IF GOTO entry through these three parts.
Click the screenshot to view the original image.
The original B-class macro program statement category uses #9003. The current standard configuration has four items for GOTO, IF GOTO, IF THEN and WHILE. Item 1, IF GOTO, illustrates the field assignments:
| Field | Current contents or setting | Role in this design |
|---|---|---|
#9003.title |
B-class macro program statement | Category name in the tree |
#9003.classify |
4 | Used by the script window's category filter |
#9003.itemnum |
4 | Number of items in this category; indexes start at 0 |
#9003.itemtype[1] |
14 | Multiline-text type, matching the entry filter |
#9003.item[1] |
IF GOTO |
Text in the first column and the fragment inserted on a double-click |
#9003.itemtitle[1] |
IF condition GOTO label | Short description in the second column, Description |
#9003.itemdesc[1] |
Detailed explanation and example of the conditional jump | Text placed in the Help box after a single click |
#9003.itemunit[1] |
Empty string | This entry has no animation path; other entries can provide one |
itemtitle is not the first column's text here, and itemdesc is not the code inserted on a double-click. The UI and scripts assign these roles. For example, this design uses itemunit for an image path rather than a displayed unit such as millimetres or degrees.
Chinese text comes from the #9003 definitions in env/i18n/translatPack-0; English text comes from translatPack-1. Structural settings such as item types and classification also come from the existing configuration data. The language pack alone is not the whole category definition.
The original accessibleDescription of treeWidget in env/mdi/mdi-main.ui contains the following two sections. mdi-aux.ui uses the same note rules.
{
-标题:(#1009_itemtitle7),500,5
-标题:(#1009_itemtitle8),200,5
-属性:-D
-T(0<<#1<<#2)
-事件: (treeDoubleClicked:/env/mdi/inserttip[1])
-事件: (treeClicked:/env/mdi/tiphelp[1])
}
{
-nodenum:#%0_itemnum
-nodeserial:0
-nodeinterval:1
-nodetitle:#%0_title
-rows:30
-serial:9000
-过滤器(#%0classify==4)
-结点过滤器(#[%%].itemtype%0==14)
-列:[-T1(#[%%].item%0) -D]
-列:[-T1(#[%%].itemtitle%0) -D]
}
The first section defines column headings, selection outputs and events. The headings come from #1009.itemtitle[7] and #1009.itemtitle[8], displayed as Sticky note set and Description in English. The original column widths are 500 and 200. In a narrow window, scroll horizontally or drag a header boundary to see the second column. The property keywords above remain as written in the original UI source.
Read the content section in this order:
| Original setting | Meaning in this tree |
|---|---|
-serial:9000, -rows:30 |
Examine 30 candidate category parameters, 9000–9029. This does not limit the tree to 30 notes. |
-过滤器(#%0classify==4) |
Create a top-level category only when its classification is 4. |
-nodetitle:#%0_title |
Read the category name from that parameter's title. |
-nodenum:#%0_itemnum |
Obtain the number of candidate child items from its itemnum. |
-nodeserial:0, -nodeinterval:1 |
Start at item 0 and examine consecutive items. |
-结点过滤器(#[%%].itemtype%0==14) |
Create a note entry only for an item whose type is 14. |
First -列 rule |
Display the item's item value: the code fragment. |
Second -列 rule |
Display the same item's itemtitle: its short description. |
Here -T1 requests string display; it does not mean “column 1.” The data items have type 14, but the tree shows both columns as string labels. Filtering the data type and choosing its display control are separate decisions.
The MDI window, mdi.ui, changes the top-level condition to classify==3, so it lists NC notes such as the G and M instruction sets. Both script windows share classification 4; MDI reads classification 3. If a category appears only in MDI, inspect its classification before changing a display script.
%0 and %% identify a particular field hereThese expressions let one set of column rules serve many categories and entries. The UI does not need a separate hard-coded rule for parameter 9003, item 1.
When creating categories, #%0 refers to the current category parameter. For example, while processing 9003, #%0_title reads #9003.title.
For the child entries, this tree supplies the category parameter number as %% and the item index as the base for %0. On the IF GOTO row:
| General expression in the UI | Field read for this entry |
|---|---|
#[%%].itemtype%0 |
#9003.itemtype[1] |
#[%%].item%0 |
#9003.item[1] |
#[%%].itemtitle%0 |
#9003.itemtitle[1] |
These are the mappings in this particular tree definition. Do not assume that %0 always means a note index in other tables or at other levels. Filtering out entries does not renumber the remaining parameter items according to their visible row positions.
This line in the first section is what makes the two shared scripts possible:
-T(0<<#1<<#2)
The leading 0 tells the tree to identify the source from the data binding of the control in column 0 of the clicked entry. It then writes the parameter number to #1 and the item index to #2. It does not pass the displayed words “IF GOTO,” nor does it read a selection parameter called #0.
Selecting IF GOTO prepares:
| Parameter | Value | Meaning |
|---|---|---|
#1 |
9003 | Which parameter contains this note |
#2 |
1 | Which item of that parameter was selected |
The original event then calls env/mdi/tiphelp. Its complete contents are:
widgetFunc["PlainTextEdit","plainTextEdit_2","clear",0]
widgetFunc["PlainTextEdit","plainTextEdit_2","insertText",^1.itemdesc[#2]]
widgetFunc["Label","label_5","setMovie",^1.itemunit[#2]]
debug ^1.itemunit[#2]
widgetFunc["Label","label_5","playMovie",0]
^1 accesses a parameter indirectly: read 9003 from #1, then access parameter 9003. For this selection, ^1.itemdesc[#2] therefore reads #9003.itemdesc[1]. The shared script does not need to know whether the selected note describes IF, WHILE or another category.
The first two lines clear the Help box and insert this item's detailed explanation. The remaining lines pass the itemunit path to label_5, set its animation and start it. debug also writes that path to the result label. An empty path can therefore clear that label; this does not mean a calculation has failed.
The original label_5 also has a visibility rule:
-C(^1.itemversion[#2]==1) -V0
Here, -V0 selects condition number 0 to determine visibility; the 0 is a condition index. That condition is ^1.itemversion[#2]==1. This UI therefore uses the selected item's itemversion as an image-display flag: a value of 1 satisfies the visibility condition. When adding illustrated help, check the resource path, the file and the display flag together.
The IF GOTO note has no picture. Open the original MDI window, expand G instruction set on the right and find G41D in the first column. Its description is Tool radius compensation left. Preserve any existing input, then single-click this entry.
The Help area displays the G41 explanation and starts the original tool-compensation animation below it. Scroll within the text box to read the longer explanation; the image occupies the lower part of the same help area.
Click the screenshot to view the original image.
Figure 7. A close-up of the original window's right side. Drag the dividers to give the text and picture enough room. The screenshot preserves the original fonts and resource, showing one frame of the playing animation.
This entry is item 41 of #9007. Following the selection rules above, a single-click sets #1=9007 and #2=41, allowing the shared script to find all the associated content:
| Field | Original content or setting | Role in this UI |
|---|---|---|
#9007.title |
G instruction set | Category name |
#9007.classify |
3 | Matches the MDI category filter |
#9007.itemtype[41] |
14 | Matches the note-entry type filter |
#9007.item[41] |
G41D |
First-column text and the fragment inserted on a double-click |
#9007.itemtitle[41] |
Tool radius compensation left | Second-column description |
#9007.itemdesc[41] |
G41 format, hints and example programs | Text placed in the Help box on a single-click |
#9007.itemunit[41] |
images/g41.gif |
Resource path passed to the animation label |
#9007.itemversion[41] |
1 | Satisfies the image area's visibility condition |
The original language script already defines the resource path and insertable fragment separately:
#9007.itemunit[41]="images/g41.gif"
#9007.item[41]="G41D"
These lines are an excerpt of the existing design; you do not need to run them again. The descriptions come from translatPack-0 or translatPack-1. The category, item type and display flag also depend on the existing parameter configuration.
The single-click sequence is:
#1 and #2.tiphelp reads the G41 explanation through ^1.itemdesc[#2] and fills plainTextEdit_2.setMovie reads images/g41.gif through ^1.itemunit[#2] and assigns that resource to label_5.playMovie starts the animation already assigned to the label.The relative image path is resolved from the application's working directory. With the standard launch arrangement, the resource is images/g41.gif under the runtime directory; images and env are sibling directories. When delivering illustrated notes, include each resource at its expected path. Copying the parameters or scripts alone does not include the image files.
This is a GIF explanation supplied with the note. Changing the left editor's text or D number does not recalculate the animation. Selecting the note does not request NC execution, so the illustration cannot establish whether your own program is correct.
Next, preserve the original draft, clear the editor and click at the desired insertion position. Double-click G41D. Only G41D is inserted on the left; the long explanation and example programs in Help are not inserted with it.
Click the screenshot to view the original image.
Figure 8. The original MDI window. The bottom message, Debugging information:images/g41.gif, comes from the help script's debug line and reports the resource path.
Stop this example after insertion. G41D still lacks a D number and the program content needed to establish compensation. Do not click Execute as though it were a complete machining program. Restore your original draft when finished.
To illustrate another note, prepare its code, explanation and resource path in separate fields, set its image-display flag to 1, and place the resource file at that path. The original tiphelp and label_5 can serve the entry without an additional image control. Maintain Chinese and English descriptions in their respective language content. Both editions of this example use the same GIF, which contains graphics and NC code. If your own images contain language-specific text, provide the corresponding resource paths as well.
A double-click also writes #1 and #2, then calls env/mdi/inserttip. This script contains only one line:
widgetFunc["PlainTextEdit","plainTextEdit","insertText",^1.item[#2]]
It inserts the selected item text into the left plainTextEdit. It neither clears that editor nor requests program execution. Detailed help and insertable text are stored separately; each shared script reads the field it needs.
The original tree's focusPolicy is Qt::NoFocus. The design lets an operator position the cursor in the editor, then click or double-click a note while retaining that editing position.
Use this sequence: click in the left editor to position the cursor → double-click a note → complete the fragment → click Execute. Moving focus to Execute invokes the original file-save rule before the file runs. If focus was previously on another button, click back in the editor first. Text inserted into a control is not by itself proof that the file has been saved.
For example, the original IF GOTO entry inserts only IF GOTO; a condition and label still have to be supplied. Notes are not buttons that execute a function immediately.
The following example appends one item to the original #9003 category and keeps the original UI and shared scripts. Work in a separate development configuration copy. Run this code once in Master Script; it uses #100 for the new index:
#100=#9003.itemnum
#9003.itemnum=#100+1
#9003.itemtype[#100]=14
#9003.item[#100]="#9999=12*8"
#9003.itemtitle[#100]="12*8=96"
#9003.itemdesc[#100]=#1009.itemtitle[5]+"96"
#9003.itemunit[#100]=""
The original category has four items, so this appends index 4 and preserves entries 0–3. The lines record the new index, extend the item count, satisfy the entry filter, store the insertable code, set the second-column description, set the help text and leave the animation path empty.
The code on the right of #9003.item[#100] is quoted. Defining the note stores that text; it does not calculate 12 × 8. The calculation runs after insertion when you click Execute. Its help reuses the current language's debugging-information prefix, producing Debugging information:96 in English and the corresponding Chinese text in Chinese.
After running the definition, close the input window and open Second Script. Expand B-class macro program statement to find #9999=12*8. Single-click it to see the help. Preserve any existing input, clear the editor, click in it, and double-click the new entry. The editor receives #9999=12*8. Click Execute to obtain 96.
Click the screenshot to view the original image.
Figure 9. Only one parameter item was added. The original header widths were adjusted to show both Sticky note set and Description; the page and handlers retain their standard design.
The complete definition is available as Append a calculation note. This is an append operation: each execution adds another item. Do not repeatedly run it from a periodic script.
To change an existing entry, update its fields at the existing parameter and item index. To add an entry, preserve the existing items and extend the count at the end. A new category also needs a name, classification and item collection, and its parameter must be within the current UI's 9000–9029 scan range. Check the project's parameter allocation before choosing a new number; an empty entry is not a permanent reservation for your use.
-D refreshes the contents of controls already created. It does not automatically create new tree nodes after itemnum changes. After changing categories, item counts or filters, closing and reopening the window is the direct way to build the tree from the revised definition.
For delivery, include the parameter definition in the component deployment process and record the allocated category and item numbers. Normal startup after installation should not append the entry again unconditionally; later updates should maintain the allocated item. Include Chinese and English titles and detailed help in the corresponding language settings, since changing current memory alone may be undone by a language pack. This example builds help from an existing translated title; to update that new help when switching languages later, assign it again as part of language handling.
Troubleshoot the definition along the same path:
| Symptom | Design point to inspect |
|---|---|
| The whole category is missing | Parameter scan range, classification required by the current window, and reopening the window. |
| The category exists but the new entry is absent | Whether itemnum includes the index and itemtype is 14. |
| Changing a title does not change the first column | The first column reads item; the second reads itemtitle. |
| Clicking one entry shows another entry's help | Column 0's binding, -T(0<<#1<<#2), and the fields read by the script. |
| Help is correct but insertion is wrong | The fragment in item, the cursor position and the original auxiliary script entry. |
| The image is absent | The itemunit path, resource file and visibility controlled by itemversion. |
| Another duplicate appears on each opening | Whether an append definition was placed in a repeatedly executed startup or periodic script. |
The same pattern can organize formulas, button-script fragments, process instructions and standard NC fragments. Adding a note supplies text and help; it does not register a new interpreter command. The fragment must still use syntax supported by its target interpreter.
Paths in this table start at the software runtime directory.
| Entry | Opening script | Original UI file | Input file | Number used by Execute |
|---|---|---|---|---|
| Master Script | env/mdi/mdi3 |
env/mdi/mdi-main.ui |
env/mdi/mainParser |
[0], main configuration script |
| Second Script | env/mdi/mdi4 |
env/mdi/mdi-aux.ui |
env/mdi/auxParser |
[1], auxiliary configuration script |
| MDI | env/mdi/mdi1 |
env/mdi/mdi.ui |
env/mdi/macroMDI1.nc |
[2], NC program |
Earlier lessons introduced #913 and #914. In the Program function area, function 8 is MDI, 9 is Master Script, and 10 is Second Script. Menu titles are in #913; button assignments and the corresponding events are in #914.
For example, the original Master Script function definition includes this mouse-release event:
-A: (MouseButtonRelease:/env/mdi/mdi3[1])
Here [1] runs the configuration script that opens the window. It has not yet run the mainParser input. This opening event does not mean that the text inside the Master Script window is executed by the auxiliary interpreter.
After preparing the parameter, mdi3 executes this section:
#1009=2
#1009.title=#1009.itemtitle[2]
#1009.item[0]=#405+"mdi/macroMDI1.nc"
#1009.item[1]=#405+"mdi/macroMDI2.nc"
#1009.item[2]=#405+"mdi/mainParser"
#1009.item[3]=#405+"mdi/auxParser"
#9999=""
MarcoDialog "/env/mdi/mdi-main.ui"
The value 2 in #1009 selects item 2. Therefore #1009.item, without an explicit index, obtains the mainParser path here. #405 provides the environment-directory prefix. Second Script selects item 3; the original MDI entry selects item 0.
Item 1, macroMDI2.nc, is another MDI input file. It is not the Second Script entry. Do not match the number 2 in that filename to the word “Second” in the menu.
The original file also has an initialization section before this code. The standard environment already defines titles and other fields for #1009. Keep the complete original file and its existing parameter definitions; do not copy only an initialization fragment over the current configuration.
The original QPlainTextEdit input uses this setting:
-T(#1009.item) -D
The corresponding items of #1009 have the filename type. The input control reads the selected file and displays its contents, then writes the edited text back when focus leaves it. -D refreshes the control from its binding.
The full code is not stored in #1009.item: the parameter stores the file path; the file stores the input text. This distinction is central to the design. Do not assume that every multiline input saves automatically in this way; its field type and control settings also matter.
The original button setting in Master Script is:
-T(#1009_itemtitle6)
-事件: (clickedEvent:/env/mdi/mainParser[0])
In Second Script it is:
-T(#1009_itemtitle6)
-事件: (clickedEvent:/env/mdi/auxParser[1])
In MDI it is:
-T(#1009_itemtitle6)
-事件: (clickedEvent[2]("mdi/"+#1009.item/"/"))
-C(#319.item3==1) -E0
The first two specify the configuration-script file and interpreter number. MDI takes the filename from the selected path, builds the NC call path, and submits it through [2]. The condition below disables the button when NC start status is 1. Execution still depends on the NC scheduler's operating conditions.
There are therefore two calls to follow: the function key opens the window; its Execute button runs the input file. The source property labels above remain as written in the original UI files; the visible button caption is Execute.
The original bottom-label setting is:
-T(#1009_itemtitle5+#9999) -D
The first part supplies the translated Debugging information: prefix; the second supplies the current result. This is a parameter display, not a separate line-by-line execution log. Other scripts or help actions that assign #9999 can change the label too.
When developing a button function, work in this order:
#9999.#9999 used during development may not be the final page's display parameter. Connect the inputs and displays required by that page.Use these checks when something differs from the example:
| Symptom | What to check first |
|---|---|
| The two developer entries are absent | Normal developer sign-in, the developer-feature setting and existing function assignments. |
| Execute appears to run older text | Whether focus left the editor, whether the top file path is correct, and whether the directory is writable. |
| The formula ran but the result label is wrong or empty | Whether the desired value was assigned to #9999, and whether later code or note help overwrote it. |
| The result disappears after reopening | The opening script intentionally clears it. Check that the code remains, then execute again. |
| A control command stops working through a different entry | Whether the main or current auxiliary window contains that control, and whether the execution number matches. |
| MDI does not proceed | Reset, an occupied NC channel, and interpretation or execution errors. |
| A syntax error follows double-clicking a note | Whether the inserted fragment is complete and placed correctly. |
Next, return to Axis configuration. Follow how a menu selection changes shared parameters and shows or hides a coordinate row. The entries introduced here let you inspect related calculations and parameter values as you learn.
Previous: Context menus and submenus · Next: Axis configuration · Reading guide