상태 머신 인스턴스화

동적으로 생성된 상태 머신과 컴파일된 상태 머신 모두 동일한 방식으로 동작하며, 동일한 속성, 상태, 데이터 모델 등을 갖습니다. 두 상태 머신의 유일한 차이점은 인스턴스화 방식뿐입니다. SCXML 파일을 사용하여 C++에서 상태 머신을 동적으로 생성하려면 다음을 사용할 수 있습니다:

auto *stateMachine = QScxmlStateMachine::fromFile("MyStatemachine.scxml");

또는 QML에서는 다음과 같이 할 수 있습니다:

import QtScxml

Item {
    property StateMachine stateMachine: scxmlLoader.stateMachine

    StateMachineLoader {
        id: scxmlLoader
        source: "statemachine.scxml"
    }
}

컴파일된 상태 머신은 다른 C++ 객체와 동일한 방식으로 인스턴스화할 수 있습니다:

auto *stateMachine = new MyStatemachine;

또는:

MyStatemachine stateMachine;

QML에서 컴파일된 상태 머신을 사용하려면, 이를 QML 유형으로 등록하면 됩니다:

struct MyStateMachineRegistration {
    Q_GADGET
    QML_NAMED_ELEMENT(MyStateMachine)
    QML_FOREIGN(MyStateMachine)
    QML_ADDED_IN_VERSION(1, 0)
};

그러면 다음과 같이 QML에서 인스턴스를 생성할 수 있습니다:

import MyStateMachine 1.0

MyStateMachine {
    id: stateMachine
}

상태 머신을 컴파일하려면 프로젝트 빌드 파일에 다음 줄을 추가해야 합니다:

cmake를 사용할 경우:

find_package(Qt6 REQUIRED COMPONENTS Scxml)
target_link_libraries(mytarget PRIVATE Qt6::Scxml)
qt_add_statecharts(mytarget
    MyStatemachine.scxml
)

qmake를 사용할 때:

QT += scxml
STATECHARTS = MyStatemachine.scxml

이렇게 하면 qmake가 qscxmlc를 실행하여 MyStatemachine.h와 MyStatemachine.cpp를 생성하고, 이를 프로젝트의 헤더 및 소스 디렉터리에 적절히 추가하도록 지시합니다. 기본적으로 생성된 파일은 빌드 디렉터리에 저장됩니다. qmake의 QSCXMLC_DIR 변수나 cmake의 OUTPUT_DIRECTORY 변수를 설정하여 다른 디렉터리를 지정할 수 있습니다. qmake의 QSCXMLC_NAMESPACE 변수나 cmake의 NAMESPACE 변수를 설정하여 상태 기계 코드를 C++ 네임스페이스에 포함시킬 수 있습니다.

상태 머신을 인스턴스화한 후에는 다음과 같이 임의의 상태의 active 속성에 연결할 수 있습니다. 예를 들어, 신호등용 상태 머신에 신호등이 빨간색임을 나타내는 상태(scxml 파일에서 "red"라는 편리한 ID를 가짐)가 있다면 다음과 같이 작성할 수 있습니다:

stateMachine->connectToState("red", [](bool active) {
    qDebug() << (active ? "entered" : "exited") << "the red state";
});

그리고 QML에서는:

Light {
    id: greenLight
    color: "green"
    visible: stateMachine.green
}

상태 머신이 이벤트를 발송할 때 알림을 받고 싶다면, 해당 신호에 연결하면 됩니다. 예를 들어, 이벤트를 발송하여 재생이 중지되었음을 알리는 미디어 플레이어 상태 머신의 경우 다음과 같이 작성할 수 있습니다:

stateMachine->connectToEvent("playbackStopped", [](const QScxmlEvent&){
    qDebug() << "Stopped!";
});

그리고 QML에서는:

import QtScxml

EventConnection {
    stateMachine: stateMachine
    events: ["playbackStopped"]
    onOccurred: console.log("Stopped!")
}

상태 머신에 이벤트를 전송하는 것도 마찬가지로 간단합니다:

stateMachine->submitEvent("tap", QVariantMap({
    { "artist", "Fatboy Slim" },
    { "title", "The Rockafeller Skank" }
}));

이렇게 하면 스테이트 머신 내부의 _event.data에 맵 내용이 포함된 "tap" 이벤트가 생성됩니다. QML에서는 다음과 같습니다:

stateMachine.submitEvent("tap", {
    "artist": "Fatboy Slim"
    "title": "The Rockafeller Skank"
})

참고: 상태머신이 올바르게 작동하려면 이벤트 루프( QEventLoop )가 필요합니다. 이벤트 루프는 이벤트에 대한 ` delay ` 속성을 구현하고, 중첩된(또는 상위) 상태 머신으로부터 이벤트를 수신했을 때 상태 머신의 처리를 스케줄링하는 데 사용됩니다. QML 애플리케이션이나 위젯 애플리케이션에서는 항상 이벤트 루프가 실행되고 있으므로 별도의 조치가 필요하지 않습니다. 다른 애플리케이션의 경우, 이벤트 루프 처리를 시작하려면 ` QApplication::run `를 호출해야 합니다.

© 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.