Quoted component paths remain literal text in a script. Read form properties in the UI event, pass plain values to a label-formatting function, and inspect the generated label before checking the printer connection.
If a label prints a brace-wrapped component path instead of a form value, fix the value assignment before changing the printer connection. In a Python-style script, a quoted path is ordinary text. Braces do not make the script read a component property. Read the properties in the form's event context, pass the resulting values to a formatting function, and inspect its output before sending anything to the printer. This separates a bad form lookup from a bad label format or a transport problem.
Match the symptom to the failing stage
Start with the earliest point where the data becomes wrong:
- The label contains braces and component names: the script probably stored a property reference as literal text.
- The event reports that a component cannot be found: the lookup starts from the wrong container, skips a level, or uses a different component name.
- The formatting function receives an old value: check when the form commits edits and which property the event reads.
- The function fails before transmission: check argument names, argument order, missing values, and numeric conversions.
- The generated label contains the correct value, but nothing prints: move to destination, connection, encoding, and printer-language checks.
- A field is absent even though its argument is correct: check that the label template actually includes that argument.
- The error handler raises a second exception: report the caught error rather than referencing an unrelated or undefined variable.
A readable label containing the wrong text is evidence that some data reached the printer. It does not establish that the application read the form correctly.
Understand why quoted paths stay literal
This assignment stores text:
roll_number = "{Form.RollNumber.intValue}"
It does not navigate to a form, find a component, or read its numeric property. The quotation marks define a string. The braces are characters within that string.
Later formatting can work correctly while producing the wrong result:
field = "ROLL: %s" % roll_number
Here, %s inserts the text already stored in roll_number. It has no knowledge of the user interface.
Removing only the quotation marks is not the repair. Expression bindings and scripts are different evaluation contexts. A property-reference syntax accepted by an expression editor is not automatically valid script syntax.
Inspect the variable immediately after assignment. Use a debugger or an approved diagnostic log, keeping sensitive production data out of shared logs. Check both the value and its type. A numeric-looking string and a numeric property can behave differently during validation and formatting.
Read the form in its event context
A shared formatting function should not search for an open window. It might be called by different windows or by code that has no user interface at all.
Read the form values in the event that initiates printing. The following example assumes a desktop HMI component API with event.source, getComponent(), and the property names shown. It is not a browser-form or gateway event example.
The assumed layout has a print button and a container named Form under the same parent. Each input is a direct child of Form:
form = event.source.parent.getComponent("Form")
roll_number = form.getComponent("RollNumber").intValue
width = form.getComponent("Width").intValue
supplier = form.getComponent("Supplier").selectedStringValue
supplier_roll = form.getComponent("SupplierRoll").text
purchase_order = form.getComponent("PurchaseOrder").text
length = form.getComponent("Length").floatValue
label_text = label_format.build_label(
roll_number,
width,
supplier,
supplier_roll,
purchase_order,
length
)
Use this structure only when it matches your actual component hierarchy. Generate property references with the event editor's property browser where available. If an input is inside another container, include that container in the lookup. event.source.parent means the immediate parent of the event source, not automatically the form or the window root.
Choose properties by meaning. A dropdown may expose a displayed label and a separate stored value. Decide which belongs on the printed label. Likewise, use a fractional numeric property when the measurement can contain decimals.
Before formatting, validate required fields, permitted ranges, units, and selection state. If an identifier can begin with zeros, keep it as text rather than reading it through an integer property.
Also confirm that the current edit has committed before the print event reads it. Follow the component's documented commit behavior rather than adding an arbitrary delay.
Build the label from plain values
Create a project-library module named label_format and put the formatting function there. Its inputs should be values, not component paths or window objects.
For a printer already configured to accept ZPL, the following example creates a small text-only label. The coordinates and font sizes are illustrative printer-dot values, not a layout sized for every label stock. Adjust the layout using the printer documentation and your actual media dimensions.
This example uses a Python 2-style runtime with unicode(). It deliberately permits only ASCII field data and rejects command delimiters and line breaks:
def safe_field(value):
if value is None:
raise ValueError("A required label field is missing")
text = unicode(value).strip()
if not text:
raise ValueError("A required label field is empty")
text.encode("ascii")
if any(mark in text for mark in ("^", "~", "\r", "\n")):
raise ValueError("A label field contains unsupported characters")
return text
def build_label(roll_number, width, supplier,
supplier_roll, purchase_order, length):
fields = {
"roll": safe_field(roll_number),
"width": safe_field(width),
"supplier": safe_field(supplier),
"supplier_roll": safe_field(supplier_roll),
"order": safe_field(purchase_order),
"length": safe_field(length)
}
template = (
"^XA\n"
"^FO25,25^A0N,28,28^FDROLL: {roll}^FS\n"
"^FO25,65^A0N,28,28^FDWIDTH: {width}^FS\n"
"^FO25,105^A0N,28,28^FDSUPPLIER: {supplier}^FS\n"
"^FO25,145^A0N,28,28^FDSUPPLIER ROLL: {supplier_roll}^FS\n"
"^FO25,185^A0N,28,28^FDORDER: {order}^FS\n"
"^FO25,225^A0N,28,28^FDLENGTH: {length}^FS\n"
"^XZ\n"
)
return template.format(**fields)
The braces in this template are deliberate formatting fields. Calling .format(**fields) substitutes the supplied values. That is different from expecting a quoted component path to evaluate itself.
Character validation here is intentionally restrictive. If your labels need accented characters or other scripts, use the printer's documented encoding and field-escaping method. Do not silently discard unsupported characters from identifiers.
Add process-specific numeric validation and decimal formatting before using the function in production. State measurement units on the label where ambiguity is possible. Also check field length: safe text can still extend beyond the printable area.
Check transport only after the label text is correct
Inspect the completed label_text before opening a connection. Confirm that every required field appears and that no component paths remain.
Then separate the remaining checks:
- Destination: confirm the configured printer address and service port against its documented setup.
- Printer language: confirm that the device accepts the command language you generated.
- Byte encoding: convert the completed text using the encoding expected by the printer and the transmission API. Do not assume that a socket method accepts a runtime string directly.
- Connection handling: use documented connection and write timeouts, and release streams and sockets even when an exception occurs.
- Error reporting: preserve the original exception and identify which stage failed without exposing unnecessary form data.
If network work could block the interface, capture the validated form values in the UI event first. Pass that snapshot to the application's documented background-work mechanism. Do not read window components from an arbitrary worker context.
A successful connection or write is not proof that a usable label printed. Avoid automatic retries when delivery is uncertain, since a retry can produce duplicate labels. Use the printer's documented status or job-feedback facilities where available.
Confirm the complete result
Check the formatter without connecting to a printer first. Supply known values and inspect the returned command text. Include cases with a missing supplier selection, a leading-zero identifier, a fractional length, a long order reference, and an unsupported character.
Next, print a controlled sample using approved nonproduction data. Compare each physical field against the captured form values. Confirm placement, clipping, units, and any barcode requirements separately. Finally, repeat the check through the actual form event so that lookup, validation, formatting, and transmission are all exercised together.
If print status also appears on a shop-floor screen, distinguish a factory status display from an operator HMI. A displayed status message should not be treated as proof of a completed print unless the application has the feedback to support it.
The useful diagnostic boundary is simple: first establish what the form supplied, then what the formatter produced, and only then what the printer received and printed.
Questions
Why does the label print a component path instead of its value?
Inside an ordinary quoted script string, braces and component names remain text. String formatting inserts that text into the label just as it would insert any other value. Read the component property through the event's documented UI API, then pass the resulting value to the formatting function.
Should the label formatting function read the form directly?
Keep form lookups in the UI event that owns the form context. A shared function can be called without an open window or from a different window. Passing plain values makes its behavior explicit and lets you check label construction without accessing the interface or connecting to a printer.
What should be checked when the generated label text is correct?
First inspect the completed label command text. If its values are correct, check the destination, printer language, byte encoding, and connection handling. A successful socket write does not establish that a physical label printed correctly. Use documented printer feedback where available and avoid blind retries that could create duplicates.
Planning information, not legal or engineering advice. Rules differ by place: check codes and permits with your local authority and your licensed trades.