Node labels (single-line, user-editable)¶
Nodes support a floating single-line textbox drawn above the node.
- User-editable. The label is a
QDMGraphicsNodeLabel(QGraphicsTextItem) child of the graphics node, so it follows node moves/drags automatically. Click to focus/edit,Entercommits,Escapereverts, focus-out commits. - Code can set it at creation time and at runtime.

Usage¶
node.setNodeLabel("intake valve")
assert node.getNodeLabel() == node.grNode.labelText() == "intake valve"
# hide / show (empty text always hides)
node.setNodeLabelVisible(False)
node.setNodeLabelVisible(True)
# gap between node top and label, px
node.setNodeLabelOffset(12)
# remove
node.clearNodeLabel()
# styling (optional)
node.grNode.setLabelColor("#ffffff")
node.grNode.setLabelFont(my_qfont)
node.grNode.setLabelBackground("#E3212121", "#FF5A5A5A")
# change notification (emitted on user commit and setNodeLabel)
node.labelChanged.connect(lambda text: print("label:", text))
Single-line is enforced: \r/\n are replaced with spaces and the result is
stripped, both for programmatic sets and user commits.
How it works¶
QDMGraphicsNode.initLabel()/QDMIconGraphicsNode.initLabel()create aQDMGraphicsNodeLabelparented to the graphics node (nodeeditor/node_graphics_node.py). Child items move with the parent, so no position tracking is needed;_updateLabelPos()only recenters it above the node after text/size changes.- The label is
ItemIsFocusablewithTextEditorInteraction, butItemIsSelectable/ItemIsMovableunset and no.nodeattribute, so rubber-band selection, node drag, andScene.getSelectedNodes()are unaffected. - Focus in/out sets
view.editingFlag(same convention asnodeeditor/node_content_widget.py) for apps that gate shortcuts while typing. - User commits go through
QDMGraphicsNodeLabel._commit()->grNode._onLabelEdited(), which emitsNode.labelChangedand stores"Node label changed"history.Node.setNodeLabel(..., store_history=True)does the same for programmatic changes; deserialize passesFalse. Node.serialize()stores'label_text','label_visible','label_offset';Node.deserialize()restores them withdata.get(...)defaults, so old.tdsfiles without the keys load with no label. Clipboard (Node.serializeround-trip) and file save/load preserve the label.