Auf dieser Seite

Qt Quick 3D - Einfaches Beispiel für die Eingabe in XR

Veranschaulicht die Controller-Eingabe in „ Qt Quick 3D “ XR.

Teekanne mit XR-Controller, dessen Strahl auf das UI-Panel mit farbigen Tasten zeigt

Dieses Beispiel zeigt, wie man die Low-Level-Eingabe-APIs in „ Qt Quick 3D “ XR nutzt, um mit 2D- und 3D-Objekten in der Szene zu interagieren. Es folgt der Grundstruktur des Beispiels „xr_simple “.

Controller-Eingabe

In diesem Beispiel führen wir „ ray picking “ von der Position des „ XrController “ aus durch:

XrController {
    id: rightController
    controller: XrController.RightController
    poseSpace: XrController.AimPose

    property QtObject hitObject

    onRotationChanged: {
        const pickResult = xrView.rayPick(scenePosition, forward)
        if (pickResult.hitType !== PickResult.Null) {
            pickRay.hit = true
            pickRay.length = pickResult.distance
            hitObject = pickResult.objectHit
            cursorSphere.position = pickResult.scenePosition
            cursorSphere.visible = true
        } else {
            pickRay.hit = false
            pickRay.length = 50
            hitObject = null
            cursorSphere.visible = false
        }
    }

    Node {
        id: pickRay
        property real length: 50
        property bool hit: false

        Model {
            eulerRotation.x: -90
            scale: Qt.vector3d(0.005, pickRay.length/100, 0.005)
            source: "#Cone"
            materials: PrincipledMaterial {
                baseColor: rightTrigger.pressed ? "#99aaff" : "#cccccc"
                lighting: PrincipledMaterial.NoLighting
            }
            opacity: 0.8
        }
    }

    Node {
        z: 5
        Model {
            eulerRotation.x: 90
            scale: Qt.vector3d(0.05, 0.10, 0.05)
            source: "#Cylinder"
            materials: PrincipledMaterial {
                baseColor: "black"
                roughness: 0.2
            }
        }
    }
}

Dies führt die folgenden Funktionen aus:

  • Wenn wir etwas treffen, ändern wir die Länge des „ pickRay “, sodass er das getroffene Objekt berührt. Der „ pickRay “ ist ein halbtransparenter Kegel (ein sich verjüngender Zylinder), der anzeigt, wohin der Benutzer zielt. Außerdem verschieben wir „ cursorSphere “ an den Punkt, an dem der Strahl auftrifft. („cursorSphere “ ist eine halbtransparente Kugel, die ein untergeordnetes Objekt von „ XrView “ ist.)
  • Wir setzen die Eigenschaft „ hitObject “ auf das Objekt, das wir getroffen haben.

Außerdem verwenden wir einen schwarzen Zylinder als allgemeine Darstellung des Controllers.

Für dieses Beispiel haben wir in der Datei „ ExampleButton.qml “ einen einfachen 3D-Druckknopf erstellt. (Die Details zur Funktionsweise des Knopfes werden hier nicht erläutert.) Wir erstellen ein „ XrInputAction “, um auf das Drücken des Knopfes zu reagieren:

XrInputAction {
    id: rightTrigger
    controller: XrInputAction.RightController
    actionId: [XrInputAction.TriggerPressed, XrInputAction.TriggerValue, XrInputAction.IndexFingerPinch]
    onTriggered: {
        const button = rightController.hitObject as ExampleButton
        if (button && button !== panel.activeButton) {
            panel.activeButton = button
        }
    }
}

Die Aktion „ rightTrigger “ reagiert auf mehrere verschiedene IDs, um sowohl die Handverfolgung als auch verschiedene Arten von Controllern zu unterstützen. Wenn die Aktion ausgelöst wird, prüft sie, ob der oben festgelegte „ hitObject “ vom Typ „ ExampleButton “ ist. In diesem Fall wird der Knopf aktiviert.

Damit ein 3D-Controller mit 2D-Inhalten interagieren kann, müssen wir eine „ XrVirtualMouse “-Aktion hinzufügen, um eine Zuordnung zwischen beiden herzustellen:

XrInputAction {
    id: rightThumbstickX
    controller: XrInputAction.RightController
    actionId: [XrInputAction.ThumbstickX]
}
XrInputAction {
    id: rightThumbstickY
    controller: XrInputAction.RightController
    actionId: [XrInputAction.ThumbstickY]
}

XrVirtualMouse {
    view: xrView
    source: rightController
    leftMouseButton: rightTrigger.pressed
    scrollWheelX: rightThumbstickX.value
    scrollWheelY: rightThumbstickY.value
}

Zunächst fügen wir zwei weitere Aktionen hinzu, um die horizontale und vertikale Position des Daumensticks zu erfassen. Dann erstellen wir ein „ XrVirtualMouse “ und verwenden dabei den „ XrController “ als Positionsquelle. Wir nutzen die zuvor erstellte Aktion „ rightTrigger “, um Mausklicks und -loslassvorgänge zu erzeugen, und verwenden die Daumenstick-Aktionen, um Mausrad-Ereignisse zu generieren.

Abschließend fügen wir ein haptisches Feedback hinzu, wenn der „ pickRay “ ein Objekt trifft:

XrHapticFeedback {
    controller: XrHapticFeedback.RightController
    condition: XrHapticFeedback.RisingEdge
    trigger: pickRay.hit
    hapticEffect: XrSimpleHapticEffect {
        amplitude: 0.5
        duration: 10
        frequency: 200
    }
}

Der haptische Effekt wird jedes Mal ausgelöst, wenn die Eigenschaft „ pickRay.hit “ von „ false “ auf „ true “ wechselt.

XrItem

Die übliche Methode, 2D-Benutzeroberflächen in 3D-Szenen einzubetten, funktioniert auch in XR. Da die Einheitsgröße jedoch einen Zentimeter beträgt, müssen diese Benutzeroberflächen skaliert werden, um nutzbar zu sein. Der Typ „ XrItem “ bietet eine bequeme Möglichkeit, die Skalierung automatisch durchzuführen, indem die physische Größe des 3D-Elements und die logische Größe der 2D-Oberfläche festgelegt werden.

XrItem {
    width: 75
    height: 100
    x: -100
    y: height + table.height + 5
    z: 40
    eulerRotation.y: 45
    color: "transparent"
    contentItem: Rectangle {
        color: Qt.rgba(1, 1, 1, 0.5)
        border.width: 5
        border.color: "lightblue"
        height: 400
        width: 300
        radius: 25
    ...
        }
    }

Wir positionieren das „ XrItem “ dreidimensional und legen eine Breite von 75 cm sowie eine Höhe von 100 cm fest. Anschließend fügen wir ein Rechteck als Inhaltselement hinzu und legen dessen Größe auf 300 × 400 Einheiten fest. Die übrigen UI-Elemente von „ Qt Quick “ werden wie gewohnt als untergeordnete Elemente des Rechtecks hinzugefügt und sind hier nicht dargestellt. Der 2D-Inhalt wird automatisch so skaliert, dass er das „ XrItem “ ausfüllt.

Beispielprojekt @ code.qt.io

© 2026 The Qt Company Ltd. Documentation contributions included herein are the copyrights of their respective owners. The documentation provided herein is licensed under the terms of the GNU Free Documentation License version 1.3 as published by the Free Software Foundation. Qt and respective logos are trademarks of The Qt Company Ltd. in Finland and/or other countries worldwide. All other trademarks are property of their respective owners.