User:Tim.Jenssen/QML Puppet Rendering in Qt Design Studio: Difference between revisions

From Qt Wiki
Jump to navigation Jump to search
(Created page with "== Architecture Overview == Qt Design Studio uses a dual-process architecture for QML editing. The main application (GUI, editors, views) talks over a local IPC channel to one or more QML Puppet processes that run headless QML engines and render the items off‑screen. {| class="wikitable" |+ Dual-process architecture |- ! QML Puppet Side<br>(QML runtime & rendering) ! Design Application Side<br>(QML document & editing UI) |- | * No visible window – renders into i...")
 
No edit summary
 
(One intermediate revision by the same user not shown)
Line 2: Line 2:
Qt Design Studio uses a dual-process architecture for QML editing.
Qt Design Studio uses a dual-process architecture for QML editing.
The main application (GUI, editors, views) talks over a local IPC channel to one or more QML Puppet processes that run headless QML engines and render the items off‑screen.
The main application (GUI, editors, views) talks over a local IPC channel to one or more QML Puppet processes that run headless QML engines and render the items off‑screen.
[[File:QMLPuppet rendering.png]]
<!--
digraph QMLPuppet {
  rankdir=LR;
  node [shape=box, style=rounded];
  subgraph cluster_ide {
    label = "Application Process";
    style = "rounded,filled";
    color = "#e6e6ff";
    ModelNode          [label="ModelNode tree\n(QML DOM)"];
    NodeInstanceView  [label="NodeInstanceView"];
    NIServerProxy      [label="NodeInstanceServerProxy"];
    FormEditorScene    [label="FormEditorScene\n(QGraphicsScene)"];
    FormEditorView    [label="FormEditorView\n(QGraphicsView)"];
  }
  subgraph cluster_puppet {
    label = "QML Puppet Process";
    style = "rounded,filled";
    color = "#fff0e6";
    NIServer          [label="NodeInstanceServer"];
    QQmlEngine        [label="QQmlEngine\n+ hidden QQuickWindow"];
    QQuickItems        [label="QQuickItem instances\n(off‑screen)"];
    NICliProxy        [label="NodeInstanceClientProxy"];
  }
  # IDE → Puppet
  ModelNode        -> NodeInstanceView  [label="(change)"];
  NodeInstanceView -> NIServerProxy      [label="createScene /\ncreateInstance /..."];
  NIServerProxy    -> NICliProxy        [style="dashed" label="QLocalSocket"];
  NICliProxy      -> NIServer;
  NIServer        -> QQmlEngine;
  QQmlEngine      -> QQuickItems        [label="instantiate"];
  # Puppet → IDE
  QQuickItems      -> NIServer          [label="renderImage(),\nboundingRect()"];
  NIServer        -> NICliProxy        [label="PixmapChanged /\nInformationChanged"];
  NICliProxy      -> NIServerProxy      [style="dashed"];
  NIServerProxy    -> NodeInstanceView;
  NodeInstanceView -> FormEditorScene    [label="update pixmaps"];
  FormEditorScene  -> FormEditorView    [label="paint + overlays"];
}
-->


{| class="wikitable"
{| class="wikitable"
Line 30: Line 74:
* non-visual view
* non-visual view
* keeps track of '''NodeInstance''' objects
* keeps track of '''NodeInstance''' objects
** live presentation of an QML item
** live presentation of a QML item
* on '''Model''' change it sends command '''to''' QML Puppet
* on '''Model''' change it sends command '''to''' QML Puppet
* monitors the QML puppet’s state
* monitors the QML puppet’s state(restart on crash)
|-
|-
|
|

Latest revision as of 13:04, 12 May 2025

Architecture Overview

Qt Design Studio uses a dual-process architecture for QML editing. The main application (GUI, editors, views) talks over a local IPC channel to one or more QML Puppet processes that run headless QML engines and render the items off‑screen. QMLPuppet rendering.png

Dual-process architecture
QML Puppet Side
(QML runtime & rendering)
Design Application Side
(QML document & editing UI)
  • No visible window – renders into images

QmlRuntime

  • QGuiApplication + QQmlEngine
  • Off‑screen: QQuickWindow + QQuickRenderControl (no QQuickView)

NodeInstanceServer

  • instantiates QQuickItems
  • executes commands from the Design Application Side
    • create scene, create instance, update property
  • sends data to the Design Application Side
    • geometries, property values, pixmaps

FormEditorView

  • built on QGraphicsView/QGraphicsScene
  • displays content by receiving rendered images and item data from the QML Puppet Side
  • draws selection borders, anchors, guidelines, and other overlays on top

NodeInstanceView

  • non-visual view
  • keeps track of NodeInstance objects
    • live presentation of a QML item
  • on Model change it sends command to QML Puppet
  • monitors the QML puppet’s state(restart on crash)

NodeInstanceClientProxy

  • mediator who dispatches the commands from the Design Application Side to the NodeInstanceServer

NodeInstanceClient

  • sends information back to the Design Application Side

NodeInstanceServerProxy

  • send origin commands
  • gets information (geometries, property values) from QML Puppet Side
  • dispatches replies to NodeInstanceView

Data Flow from ModelNode to Rendered Item

  • ModelNode = QML DOM node without runtime.
    • Wrapped by QmlItemNode / QmlObjectNode for Qt Quick semantics supplied by the QML Puppet.
  • Qt Design Studio launches QML Puppet and calls
    QQuickDesignerSupport::activateDesignerMode()
    
    • disables animations & user input during design.
  • Qt Design Studio sends a CreateSceneCommand containing the entire ModelNode hierarchy.
    • Each node is paired with an InstanceContainer (type, id …).
  • Puppet’s NodeInstanceServer builds real QObject / QQuickItem instances, importing required QML modules.
    • Nodes such as States or Behavior can be skipped or handled specially.
  • After instantiation QML Puppet returns:
    • InformationChangedCommand – geometry, implicit size …
    • PixmapChangedCommand – rendered image(s)
  • Qt Design Studio NodeInstanceView matches the data by id, updates its NodeInstance cache and triggers a repaint in FormEditorScene.
  • Rendering pipeline inside the QML Puppet:
    • Scene graph driven manually via QQuickRenderControl
    • Root item parented to an off‑screen content item inside the hidden QQuickWindow.
    • Grabs whole window or individual items (grabToImage) into QImage`s.
  • Large images are transferred through shared memory, and commands travel through a QLocalSocket stream.

Visual Representation Differences (QML Puppet vs Running App)

  • Animations paused – timeline is frozen unless explicitly previewed.
  • No real user input – mouse / key events are not forwarded by default.
  • Native text AA disabled – to avoid platform‑specific artefacts.
  • Single‑frame snapshot of OpenGL / particle effects – continuous effects are sampled at render time.
  • Root item forced to (0 ; 0) – avoids clipping and simplifies layout.
  • Composed by QGraphicsScene – Minor alpha‑blending or DPI rounding differences are possible.