TaskTree 신호등
신호등 시뮬레이션을 통해 TaskTree를 사용하여 상태 기계 동작을 구현하는 방법을 보여줍니다.
TaskTree 신호등 은 Qt SCXML 및 Qt State Machine에 있는 신호등 예제의 대체 구현 방식입니다.

이 애플리케이션은 세 가지 주요 구성 요소로 이루어져 있습니다:
- 현재 상태를 표시하는 ‘
TrafficLight’ 위젯. - 상태 전환을 제어하는 `
TaskTree` 레시피. - UI와 상태 머신을 동기화하는
GlueInterface.
다음 섹션에서는 이 예제의 코드에 대해 더 자세히 설명합니다.
헬퍼 글루 클래스
GlueInterface 클래스는 UI와 운영 로직을 명확하게 분리해 줍니다.
enum class Light
{
Off = 0,
Red = 1 << 0,
Yellow = 1 << 1,
Green = 1 << 2,
};
Q_DECLARE_FLAGS(Lights, Light)
Q_DECLARE_OPERATORS_FOR_FLAGS(Lights)
class GlueInterface final : public QObject
{
Q_OBJECT
public:
// operational logic -> GUI
void setLights(Lights lights) { emit lightsChanged(lights); }
// GUI -> operational logic
void smash() { emit smashed(); }
void repair() { emit repaired(); }
signals:
void lightsChanged(Lights lights);
void smashed();
void repaired();
};GlueInterface 클래스는 다음과 같은 인터페이스 메서드를 제공합니다:
| 메서드 | 목적 |
|---|---|
setLights() | TaskTree 레시피에서 신호등 상태를 업데이트합니다 |
lightsChanged() | 신호등 상태가 변경될 때 UI에 알립니다 |
smash()/ repair() | 오류 시뮬레이션 및 복구 작업을 처리합니다 |
사용자가 UI와 상호작용할 때:
- '일시 중지'를 클릭하면 `
smash()`가 트리거되어 오류를 시뮬레이션합니다. - 재생 버튼을 클릭하면 `
repair()`가 트리거되어 정상 작동을 복원합니다.
상태 머신 구현
상태 머신 로직은 TaskTree 레시피를 통해 구현됩니다. ` recipe() ` 메서드는 ` GlueInterface`에 대한 참조를 사용하여 이 로직을 생성합니다:
ExecutableItem recipe(GlueInterface &iface)
{
return Forever {
Group { // "working" state
stopOnSuccess,
parallel,
signalAwaiterTask(&iface, &GlueInterface::smashed), // transitions to the "broken" state
Forever {
switchLightsTask(&iface, Light::Red, 3s), // "red" state
switchLightsTask(&iface, Light::Red | Light::Yellow, 1s), // "redGoingGreen" state
switchLightsTask(&iface, Light::Green, 3s), // "green" state
switchLightsTask(&iface, Light::Yellow, 1s), // "greenGoingRed" state
}
},
Group { // "broken" state
stopOnSuccess,
parallel,
signalAwaiterTask(&iface, &GlueInterface::repaired), // transitions to the "working" state
Forever {
switchLightsTask(&iface, Light::Yellow, 1s), // "blinking" state
switchLightsTask(&iface, Light::Off, 1s), // "unblinking" state
}
}
};
}루트 상태 관리
최상위 Forever 항목은 자식 노드들을 무한 루프에서 실행합니다. 여기에는 정상 상태와 고장 상태를 나타내는 두 개의 하위 그룹이 포함되어 있습니다.
상태 전환 규칙:
- 기본 execution mode 가 sequential 이므로 상태들은 순차적으로 실행됩니다.
- 한 상태가 완료되면 다른 상태가 시작됩니다.
- 사용자가 UI에서 일시 정지 또는 재생 버튼을 클릭하여 해당 신호를 발생시키면 상태 전환이 트리거됩니다.
"정상" 작동 상태
" working " 작업 상태( Group )는 " parallel" 상태에서 실행되는 두 가지 작업으로 구성됩니다:
- signalAwaiterTask 는
GlueInterface::smashed신호에 연결됩니다. 신호가 트리거되면, 해당 태스크는 즉시 DoneResult::Success 로 종료됩니다. 이로 인해 Group 의 실행이 중지되고, 레시피는 "broken" 상태로 전환됩니다. - 중첩된 ‘ Forever ’ 태스크는 4개의 ‘
switchLightsTask’ 태스크(“red”, “redGoingGreen”, “green”, “greenGoingRed”)로 구성되어 있으며, 이 태스크들은 sequentially 무한 루프에서 실행됩니다.
각 그룹의 stopOnSuccess 항목은 자식 태스크 중 하나가 DoneResult::Success 로 완료되면 실행을 중지하도록 지시합니다.
switchLightsTask 구현:
GlueInterface::setLights()을 통해 조명 상태를 업데이트합니다.- timeoutTask 를 사용하여 시간 지연 효과를 생성합니다.
timeout를 통해 지정된 기간 동안 상태를 유지합니다.
static Group switchLightsTask(GlueInterface *iface, Lights lights, const milliseconds &timeout)
{
return {
onGroupSetup([iface, lights] { iface->setLights(lights); }),
timeoutTask(timeout, DoneResult::Success)
};
}"오류가 발생한" 작동 상태
"고장" 상태의 Group 는 정상 작동 상태의 Group 와 유사합니다. 유일한 차이점은 GlueInterface::repaired 신호에 연결되어 있으며, 조명이 노란색 조명을 켜고 끄는 두 가지 상태 사이만 순환한다는 점입니다.
애플리케이션 설정
메인 애플리케이션 설정에서는 모든 컴포넌트를 생성하고 연결합니다:
int main(int argc, char **argv)
{
QApplication app(argc, argv);
GlueInterface iface;
QTaskTree taskTree({recipe(iface)});
TrafficLight widget(iface);
widget.show();
taskTree.start();
return app.exec();
}main() 함수는 QApplication, GlueInterface, QTaskTree 및 TrafficLight 객체를 인스턴스화합니다.
taskTree 객체를 생성하기 위해, iface 객체로 생성된 recipe() 객체를 전달합니다. widget 도 전달받은 iface 객체를 사용합니다.
애플리케이션을 실행하기 전에, ` main() ` 함수는 ` TrafficLight ` 위젯을 표시하고 작업 트리를 시작합니다.
예제 실행
다음 위치에서 예제를 실행할 수 있습니다.
- Qt Creator
Welcome 모드를 열고 Examples 에서 예제를 선택하십시오. 자세한 내용은 Qt Creator 의 ‘튜토리얼: 빌드 및 실행’을 참조하십시오.
- Qt Extension for Visual Studio Code
Command Palette 에서 Qt: Open Qt examples 명령을 실행하고 목록에서 예제를 선택하십시오. 자세한 내용은 Qt Extension for Visual Studio Code: 튜토리얼: 빌드 및 실행을 참조하십시오.
© 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.