C++ GUI QT (Trafic Light)

I have to write a GUI application for Traffic light - Green/Yellow/Red im allowed to specify the time interval once on the GUI for the colors and it should not change during the execution - First Green then yellow then red. The 3 colors are .jpg files

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
  #include "mainwindow.h"
#include "ui_mainwindow.h"
#include <QApplication>
#include <QWidget>
#include <QLabel>
#include <QPushButton>
#include <QGridLayout>
#include <QTimer>

MainWindow::MainWindow(QWidget *parent) :
    QMainWindow(parent),
    ui(new Ui::MainWindow)
{
    ui->setupUi(this);
}

MainWindow::~MainWindow()
{
    delete ui;
}

class TrafficLightWidget : public QWidget {
public:
    TrafficLightWidget(QWidget *parent = nullptr) : QWidget(parent) {
        // Set up the layout
        QGridLayout *layout = new QGridLayout(this);

        // Create the labels to display the traffic light colors
        greenLabel = new QLabel(this);
        yellowLabel = new QLabel(this);
        redLabel = new QLabel(this);

        // Create the button to start the traffic light
        startButton = new QPushButton("Start", this);

        // Add the labels and button to the layout
        layout->addWidget(greenLabel, 0, 0);
        layout->addWidget(yellowLabel, 0, 1);
        layout->addWidget(redLabel, 0, 2);
        layout->addWidget(startButton, 1, 0, 1, 3);

        // Connect the start button to the startTrafficLight() slot
        connect(startButton, &QPushButton::clicked, this, &TrafficLightWidget::startTrafficLight);
    }

private slots:
    void startTrafficLight() {
        // Disable the button to prevent changing the time interval during execution
        startButton->setEnabled(false);

        // Set the default time interval in milliseconds (change this to desired interval)
        int timeInterval = 2000;

        // Load the image files for green, yellow, and red lights
        QPixmap greenPixmap("green.jpg");
        QPixmap yellowPixmap("yellow.jpg");
        QPixmap redPixmap("red.jpg");

        // Set the images for the labels
        greenLabel->setPixmap(greenPixmap);
        yellowLabel->setPixmap(yellowPixmap);
        redLabel->setPixmap(redPixmap);

        // Hide the yellow and red lights at the beginning
        yellowLabel->hide();
        redLabel->hide();

        // Create a QTimer to handle the time intervals
        QTimer *timer = new QTimer(this);

        // Connect the timer's timeout signal to the updateTrafficLight() slot
        connect(timer, &QTimer::timeout, this, &TrafficLightWidget::updateTrafficLight);

        // Start the timer with the specified time interval
        timer->start(timeInterval);
    }

    void updateTrafficLight() {
        // Toggle the visibility of the lights
        if (greenLabel->isVisible()) {
            greenLabel->hide();
            yellowLabel->show();
        } else if (yellowLabel->isVisible()) {
            yellowLabel->hide();
            redLabel->show();
        } else if (redLabel->isVisible()) {
            redLabel->hide();
            greenLabel->show();
        }
    }

private:
    QLabel *greenLabel;
    QLabel *yellowLabel;
    QLabel *redLabel;
    QPushButton *startButton;
};

int main(int argc, char **argv)
{
    QApplication app(argc, argv);

    widget.resize(110, 300);
    widget.show();


    return app.exec();
}
My header and .pro file is the following :

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
#ifndef MAINWINDOW_H
#define MAINWINDOW_H

#include <QMainWindow>

namespace Ui {
class MainWindow;
}

class MainWindow : public QMainWindow
{
    Q_OBJECT

public:
    explicit MainWindow(QWidget *parent = 0);
    ~MainWindow();

private:
    Ui::MainWindow *ui;
};

#endif // MAINWINDOW_H 



1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
QT       += core gui

greaterThan(QT_MAJOR_VERSION, 4): QT += widgets

TARGET = untitled4
TEMPLATE = app


SOURCES +=\
        mainwindow.cpp

HEADERS  += mainwindow.h

FORMS    +=
QMAKE_CXXFLAGS += -std=c++0x



My code is not working and I also still need to add the .jpg files
Last edited on
My code is not working

What exactly is "not working" ???

and I also still need to add the .jpg files

It's probably best to "embed" such files, via Qt's resource system, so that you don't have to worry about loading the required file (and hoping that the required file is present at the expected location) at runtime. See here for details:
https://doc.qt.io/qt-5/resources.html

If you really want to load the file at runtime, always load from QCoreApplication::applicationDirPath(), not from "current" directory.
Last edited on
basicly its not running
Widget was not declared in this scope at line 103-104


I want to see if it visually works but since its not executing I can't
My code is not working


In what way? Does it compile OK? If it does, what's it doing/not doing against what is expected? What debugging have you done?
Widget was not declared in this scope at line 103-104

Yeah, because you are trying to use variable widget, which obviously was never declared 😏

That's nothing Qt-specific, but basic C/C++. Can't use a variable that you haven't declared!

Try something like:
1
2
3
4
5
6
7
8
9
10
11
int main(int argc, char **argv)
{
    QApplication app(argc, argv);

    MainWindow *window = new MainWindow();
    window->whatever();
    
    /* ... */

    delete window;
}
Last edited on
What its doing now is "Displaying" but a big white box that looks like a Traffic light with no lights
I would suggest that you make one step after another.
First display a single image and then the other. After that use the timer.

One problem you might have is hide()/show() which may break the layout.
I suggest that instead of hide() set a pixmap like "off.jpg". And show() of course the other colors.
In your code, you are loading "green.jpg" and friends without a path, making the code depend on whatever the "current" directory happens to be. Since what the "current" directory is going to be at runtime isn't usually under your control, this is very likely to break!

As said before, embed them as resources into the EXE file, or, at least, load them relative to QCoreApplication::applicationDirPath().

https://doc.qt.io/qt-6/resources.html
https://doc.qt.io/qt-6/qcoreapplication.html#applicationDirPath
Last edited on
@kigar64551 Im just gonna use the path of the x3 for now as I only need to submit screenshots of it so its fine. I was able to get it to display but I have 1 problem. I set the intervals to 2000 meaning 2 sec each its displaying Green-Yellow-Red-Green-Yellow-Red which is fine. But its Horizontal , how can I change it to display vertical?
Use a QVBoxLayout?
https://doc.qt.io/qt-6/qvboxlayout.html#details

Either that, or when add()'ing the widgets to the QGridLayout, set row and column accordingly, i.e. each element on a separate row.
https://doc.qt.io/qt-6/qgridlayout.html#addWidget-1

BTW: Instead of hiding the "inactive" light bulbs (QLabels) of your traffic light, you probably want to show a picture (QPixmap) of a turned-off light bulb at those places. It's not like the light bulbs of a traffic light appear and disappear; they just turn on and off 😏

(In other words, don't show/hide the QLabels, just swap their QPixmaps, i.e. pictures, as needed)
Last edited on
Topic archived. No new replies allowed.