1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137
|
// Copyright (C) 2023 The Qt Company Ltd.
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause
#include "trafficlight.h"
#include <QtWidgets/qboxlayout.h>
#include <QtGui/qpainter.h>
using namespace Qt::Literals::StringLiterals;
class TrafficLightWidget : public QWidget
{
public:
TrafficLightWidget(QWidget *parent = nullptr)
: QWidget(parent), m_background(":/background.png"_L1)
{
QVBoxLayout *vbox = new QVBoxLayout(this);
vbox->setContentsMargins(0, 40, 0, 80);
m_red = new LightWidget(":/red.png"_L1);
vbox->addWidget(m_red, 0, Qt::AlignHCenter);
m_yellow = new LightWidget(":/yellow.png"_L1);
vbox->addWidget(m_yellow, 0, Qt::AlignHCenter);
m_green = new LightWidget(":/green.png"_L1);
vbox->addWidget(m_green, 0, Qt::AlignHCenter);
setLayout(vbox);
}
LightWidget *redLight() const
{ return m_red; }
LightWidget *yellowLight() const
{ return m_yellow; }
LightWidget *greenLight() const
{ return m_green; }
void paintEvent(QPaintEvent *) override
{
QPainter painter(this);
painter.setRenderHint(QPainter::Antialiasing);
painter.drawImage(0, 0, m_background);
}
QSize sizeHint() const override
{
return m_background.size();
}
private:
QImage m_background;
LightWidget *m_red;
LightWidget *m_yellow;
LightWidget *m_green;
};
TrafficLight::TrafficLight(QScxmlStateMachine *machine, QWidget *parent)
: QWidget(parent)
, m_machine(machine)
{
TrafficLightWidget *widget = new TrafficLightWidget(this);
setFixedSize(widget->sizeHint());
machine->connectToState(u"red"_s, widget->redLight(), &LightWidget::switchLight);
machine->connectToState(u"redGoingGreen"_s, widget->redLight(), &LightWidget::switchLight);
machine->connectToState(u"yellow"_s, widget->yellowLight(), &LightWidget::switchLight);
machine->connectToState(u"blinking"_s, widget->yellowLight(), &LightWidget::switchLight);
machine->connectToState(u"green"_s, widget->greenLight(), &LightWidget::switchLight);
QAbstractButton *button = new ButtonWidget(this);
auto setButtonGeometry = [this, button](){
QSize buttonSize = button->sizeHint();
button->setGeometry(width() - buttonSize.width() - 20,
height() - buttonSize.height() - 20,
buttonSize.width(), buttonSize.height());
};
connect(button, &QAbstractButton::toggled, this, setButtonGeometry);
setButtonGeometry();
connect(button, &QAbstractButton::toggled, this, &TrafficLight::toggleWorking);
}
void TrafficLight::toggleWorking(bool pause)
{
m_machine->submitEvent(pause ? "smash" : "repair");
}
LightWidget::LightWidget(const QString &image, QWidget *parent)
: QWidget(parent)
, m_image(image)
{}
bool LightWidget::isOn() const
{ return m_on; }
void LightWidget::setOn(bool on)
{
if (on == m_on)
return;
m_on = on;
update();
}
void LightWidget::switchLight(bool onoff)
{
setOn(onoff);
}
void LightWidget::paintEvent(QPaintEvent *)
{
if (!m_on)
return;
QPainter painter(this);
painter.setRenderHint(QPainter::Antialiasing);
painter.drawImage(0, 0, m_image);
}
QSize LightWidget::sizeHint() const
{
return m_image.size();
}
ButtonWidget::ButtonWidget(QWidget *parent) :
QAbstractButton(parent), m_playIcon(":/play.png"_L1),
m_pauseIcon(":/pause.png"_L1)
{
setCheckable(true);
}
void ButtonWidget::paintEvent(QPaintEvent *)
{
QPainter painter(this);
painter.setRenderHint(QPainter::Antialiasing);
painter.drawImage(0, 0, isChecked() ? m_playIcon : m_pauseIcon);
}
QSize ButtonWidget::sizeHint() const
{
return isChecked() ? m_playIcon.size() : m_pauseIcon.size();
}
|