신호등
'신호등' 예제는 Qt State Machine Overview를 사용하여 신호등의 제어 흐름을 구현하는 방법을 보여줍니다.

이 예제에서는 TrafficLightWidget 클래스를 작성합니다. 이 신호등에는 빨간색, 노란색, 녹색 세 가지 신호등이 있습니다. 신호등은 일정 간격마다 한 신호에서 다른 신호로(빨간색 → 노란색 → 녹색 → 노란색 → 다시 빨간색) 전환됩니다.
class LightWidget : public QWidget
{
Q_OBJECT
Q_PROPERTY(bool on READ isOn WRITE setOn)
public:
explicit LightWidget(const QColor &color, QWidget *parent = nullptr)
: QWidget(parent), m_color(color)
{
}
bool isOn() const { return m_on; }
void setOn(bool on)
{
if (on == m_on)
return;
m_on = on;
update();
}
public slots:
void turnOff() { setOn(false); }
void turnOn() { setOn(true); }
protected:
void paintEvent(QPaintEvent *) override
{
if (!m_on)
return;
QPainter painter(this);
painter.setRenderHint(QPainter::Antialiasing);
painter.setBrush(m_color);
painter.drawEllipse(rect());
}
private:
QColor m_color;
bool m_on = false;
};LightWidget 클래스는 신호등의 개별 등 하나를 나타냅니다. 이 클래스는 on 속성과, 각각 불을 켜고 끄는 데 사용되는 turnOn() 및 turnOff() 슬롯 두 개를 제공합니다. 이 위젯은 생성자에 전달된 색상으로 자체적으로 렌더링됩니다.
class TrafficLightWidget : public QWidget
{
Q_OBJECT
public:
explicit TrafficLightWidget(QWidget *parent = nullptr) : QWidget(parent)
{
auto vbox = new QVBoxLayout(this);
m_red = new LightWidget(Qt::red);
vbox->addWidget(m_red);
m_yellow = new LightWidget(Qt::yellow);
vbox->addWidget(m_yellow);
m_green = new LightWidget(Qt::green);
vbox->addWidget(m_green);
auto pal = palette();
pal.setColor(QPalette::Window, Qt::black);
setPalette(pal);
setAutoFillBackground(true);
}
LightWidget *redLight() const { return m_red; }
LightWidget *yellowLight() const { return m_yellow; }
LightWidget *greenLight() const { return m_green; }
private:
LightWidget *m_red;
LightWidget *m_yellow;
LightWidget *m_green;
};TrafficLightWidget 클래스는 신호등의 시각적 부분을 나타냅니다. 이 위젯은 세 개의 신호등을 수직으로 배열하여 포함하고 있으며, 이에 대한 액세서 함수를 제공합니다.
QState *createLightState(LightWidget *light, int duration, QState *parent = nullptr)
{
auto lightState = new QState(parent);
auto timer = new QTimer(lightState);
timer->setInterval(duration);
timer->setSingleShot(true);
auto timing = new QState(lightState);
QObject::connect(timing, &QAbstractState::entered, light, &LightWidget::turnOn);
QObject::connect(timing, &QAbstractState::entered, timer, QOverload<>::of(&QTimer::start));
QObject::connect(timing, &QAbstractState::exited, light, &LightWidget::turnOff);
auto done = new QFinalState(lightState);
timing->addTransition(timer, &QTimer::timeout, done);
lightState->setInitialState(timing);
return lightState;
}createLightState() 함수는 해당 상태로 진입하면 신호등을 켜고, 상태에서 벗어나면 신호등을 끄는 상태를 생성합니다. 이 상태는 타이머를 사용하며, 곧 보게 되겠지만 타임아웃은 한 LightState에서 다른 LightState로 전환하는 데 사용됩니다. 다음은 신호등 상태에 대한 상태 차트입니다:

class TrafficLight : public QWidget
{
Q_OBJECT
public:
explicit TrafficLight(QWidget *parent = nullptr) : QWidget(parent)
{
auto vbox = new QVBoxLayout(this);
auto widget = new TrafficLightWidget;
vbox->addWidget(widget);
vbox->setContentsMargins(QMargins());
auto machine = new QStateMachine(this);
auto redGoingYellow = createLightState(widget->redLight(), 3000);
redGoingYellow->setObjectName("redGoingYellow");
auto yellowGoingGreen = createLightState(widget->yellowLight(), 1000);
yellowGoingGreen->setObjectName("yellowGoingGreen");
redGoingYellow->addTransition(redGoingYellow, &QState::finished, yellowGoingGreen);
auto greenGoingYellow = createLightState(widget->greenLight(), 3000);
greenGoingYellow->setObjectName("greenGoingYellow");
yellowGoingGreen->addTransition(yellowGoingGreen, &QState::finished, greenGoingYellow);
auto yellowGoingRed = createLightState(widget->yellowLight(), 1000);
yellowGoingRed->setObjectName("yellowGoingRed");
greenGoingYellow->addTransition(greenGoingYellow, &QState::finished, yellowGoingRed);
yellowGoingRed->addTransition(yellowGoingRed, &QState::finished, redGoingYellow);
machine->addState(redGoingYellow);
machine->addState(yellowGoingGreen);
machine->addState(greenGoingYellow);
machine->addState(yellowGoingRed);
machine->setInitialState(redGoingYellow);
machine->start();
}
};TrafficLight 클래스는 TrafficLightWidget과 상태 머신을 결합한 것입니다. 상태 그래프에는 빨간색→노란색, 노란색→초록색, 초록색→노란색, 노란색→빨간색의 네 가지 상태가 있습니다. 초기 상태는 red-to-yellow이며, 이 상태의 타이머가 만료되면 상태 머신은 yellow-to-green 상태로 전환됩니다. 다른 상태들에서도 동일한 과정이 반복됩니다. 상태도는 다음과 같습니다:

int main(int argc, char **argv)
{
QApplication app(argc, argv);
TrafficLight widget;
widget.resize(110, 300);
widget.show();
return app.exec();
}main() 함수는 TrafficLight 객체를 생성하고 이를 표시합니다.
© 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.