You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何将同一StateMachine重复应用于多个QML列元素(如signal1与signal2)

Great question! You don't need to modify any C++ code—all you need to do is adjust your QML file to reuse the existing TrafficLightStateMachine logic for signal2 (and future traffic light components).

Why no C++ changes are needed

Your existing TrafficLightStateMachine is already exposed as a property of the root Image component (lights.stateMachine), and it emits all the state signals (red, redGoingGreen, etc.) that you need. The state machine itself doesn't care which QML components are listening to its state changes—it just broadcasts the current state. So we can reuse it across multiple traffic light groups without touching C++.

How to update the QML

There are two approaches you can take, depending on how scalable you want the solution to be:

Approach 1: Quick fix (direct updates to existing States)

Modify each existing State in your lights component to include property changes for signal2's lights, alongside signal1's. For example:

states: [
    State {
        name: "Red"
        when: stateMachine.red
        // Update signal1's lights
        PropertyChanges { target: redLight; opacity: 1 }
        PropertyChanges { target: yellowLight; opacity: 0.2 }
        PropertyChanges { target: greenLight; opacity: 0.2 }
        // Update signal2's lights
        PropertyChanges { target: redLight1; opacity: 1 }
        PropertyChanges { target: yellowLight1; opacity: 0.2 }
        PropertyChanges { target: greenLight1; opacity: 0.2 }
    },
    State {
        name: "RedGoingGreen"
        when: stateMachine.redGoingGreen
        PropertyChanges { target: redLight; opacity: 1 }
        PropertyChanges { target: yellowLight; opacity: 1 }
        PropertyChanges { target: greenLight; opacity: 0.2 }
        PropertyChanges { target: redLight1; opacity: 1 }
        PropertyChanges { target: yellowLight1; opacity: 1 }
        PropertyChanges { target: greenLight1; opacity: 0.2 }
    },
    State {
        name: "Yellow"
        when: stateMachine.yellow
        PropertyChanges { target: redLight; opacity: 0.2 }
        PropertyChanges { target: yellowLight; opacity: 1 }
        PropertyChanges { target: greenLight; opacity: 0.2 }
        PropertyChanges { target: redLight1; opacity: 0.2 }
        PropertyChanges { target: yellowLight1; opacity: 1 }
        PropertyChanges { target: greenLight1; opacity: 0.2 }
    },
    State {
        name: "Green"
        when: stateMachine.green
        PropertyChanges { target: redLight; opacity: 0.2 }
        PropertyChanges { target: yellowLight; opacity: 0.2 }
        PropertyChanges { target: greenLight; opacity: 1 }
        PropertyChanges { target: redLight1; opacity: 0.2 }
        PropertyChanges { target: yellowLight1; opacity: 0.2 }
        PropertyChanges { target: greenLight1; opacity: 1 }
    }
]

This will immediately sync signal2's state with signal1 using the same state machine.

Approach 2: Scalable solution (create a reusable TrafficLight component)

If you plan to add more traffic light components in the future, wrapping the light group into a reusable QML component will save you repetition.

  1. Create a new file named TrafficLight.qml with this content:
import QtQuick 2.5

Column {
    // Expose aliases for the lights so parent components can control them
    property alias redLight: redLight
    property alias yellowLight: yellowLight
    property alias greenLight: greenLight

    width: 22
    height: 120
    spacing: 27

    Image {
        id: redLight
        width: 20
        height: 20
        opacity: 0.2
        source: "red.png"
    }
    Image {
        id: yellowLight
        width: 20
        height: 20
        opacity: 0.2
        source: "yellow.png"
    }
    Image {
        id: greenLight
        width: 20
        height: 20
        opacity: 0.2
        source: "green.png"
    }
}
  1. Replace the two Column components in Lights.ui.qml with this reusable component:
TrafficLight {
    id: signal1
    y: 286
    layer.smooth: true
    layer.enabled: false
    rotation: 0
    transformOrigin: Item.Center
    anchors.horizontalCenterOffset: -87
    anchors.horizontalCenter: parent.horizontalCenter
}

TrafficLight {
    id: signal2
    x: -8
    y: 237
    rotation: 270
    transformOrigin: Item.Center
    anchors.horizontalCenter: parent.horizontalCenter
    anchors.horizontalCenterOffset: 124
}
  1. Update your states to reference the component's aliased lights (this looks cleaner and is easier to extend):
states: [
    State {
        name: "Red"
        when: stateMachine.red
        PropertyChanges { target: signal1.redLight; opacity: 1 }
        PropertyChanges { target: signal1.yellowLight; opacity: 0.2 }
        PropertyChanges { target: signal1.greenLight; opacity: 0.2 }
        PropertyChanges { target: signal2.redLight; opacity: 1 }
        PropertyChanges { target: signal2.yellowLight; opacity: 0.2 }
        PropertyChanges { target: signal2.greenLight; opacity: 0.2 }
    },
    // Repeat the pattern for RedGoingGreen, Yellow, Green states
]

Now, adding a new traffic light is as simple as dropping another TrafficLight component into your QML and adding its property changes to the states (or even using a Repeater if you have many identical lights!).

Final Notes

The key here is that your TrafficLightStateMachine is already a shared state source—you just need to connect additional QML components to its state signals. If you ever want each traffic light to have independent state logic later, you'd need to create separate instances of TrafficLightStateMachine, but that's not required for your current use case.

内容的提问来源于stack exchange,提问作者SHREERAKSHA BHAT

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.04.29 00:32:30