상태 머신 인스턴스화

동적으로 생성된 상태 머신과 컴파일된 상태 머신은 모두 동일한 방식으로 동작하며 동일한 속성, 상태, 데이터 모델 등을 갖습니다. 인스턴스화되는 방식만 다를 뿐입니다. 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가 MyStatemachine.h 및 MyStatemachine.cpp를 생성하고 프로젝트 헤더와 소스에 적절하게 추가하는 qscxmlc를 실행하도록 지시합니다. 기본적으로 생성된 파일은 빌드 디렉터리에 저장됩니다. 다른 디렉터리를 지정하도록 qmake QSCXMLC_DIR 또는 cmake OUTPUT_DIRECTORY 변수를 설정할 수 있습니다. 상태 머신 코드를 C++ 네임스페이스에 넣으려면 qmake QSCXMLC_NAMESPACE 또는 cmake NAMESPACE 변수를 설정할 수 있습니다.

상태 머신을 인스턴스화한 후에는 다음과 같이 모든 상태의 활성 프로퍼티에 연결할 수 있습니다. 예를 들어 신호등에 대한 상태 머신에 신호등이 빨간색임을 나타내는 상태(scxml 파일에서 편리한 ID "red"가 있음)가 있는 경우 다음과 같이 작성할 수 있습니다:

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에서 사용할 수 있는 맵 콘텐츠가 포함된 '탭' 이벤트가 생성됩니다. QML에서는

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

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

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