Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • Users
  • Groups
  • Search
  • Get Qt Extensions
  • Unsolved
Collapse
Brand Logo
  1. Home
  2. Qt Development
  3. General and Desktop
  4. TrafficLight example as a widget in MainWindow

TrafficLight example as a widget in MainWindow

Scheduled Pinned Locked Moved Unsolved General and Desktop
14 Posts 3 Posters 3.5k Views 2 Watching
  • Oldest to Newest
  • Newest to Oldest
  • Most Votes
Reply
  • Reply as topic
Log in to reply
This topic has been deleted. Only users with topic management privileges can see it.
  • T Offline
    T Offline
    Tobias89
    wrote on last edited by A Former User
    #1

    Hi everybody,

    I have a problem and I don't know what to do.
    I want to use the trafficlight example as a smaller widget in my mainwindow. So that the trafficlight is running in my mainwindow and not as a seperate window.

    What I have done....
    I used the source code of the trafficlight example and divided it into more files (seperated the classes to files). Then I modified the code at some places to get more overview. At last I create my mainwindow class and there I show my trafficlightwidget.

    My problem...
    The trafficlightwidget will be displayed in my mainwindow, as I want (black area). But the lightwidgets (green, yellow, red) will not be shown. When I show my trafficlightwidget in a seperate window everything is fine. But within the mainwindow it don't show the lightwidgets.
    I have also tried to use the update() function of the trafficlightwidget and the mainwindow, but nothing happens. :-(

    Can anybody help me? Thank you in advance!!!

    Best regards
    Tobias

    My code:
    main.cpp

    int main(int argc, char *argv[])
    {
        QApplication a(argc, argv);
    
        MainWindow w;
        TrafficLightWidget tl;
        TrafficLightController tlc;
    
        QObject::connect(&tlc, SIGNAL(greenChanged(bool)), &tl, SLOT(greenisOn(bool)));
        QObject::connect(&tlc, SIGNAL(yellowChanged(bool)), &tl, SLOT(yellowisOn(bool)));
        QObject::connect(&tlc, SIGNAL(redChanged(bool)), &tl, SLOT(redisOn(bool)));
    
        w.show();
    
        return a.exec();
    }
    

    mainwindow.h

    namespace Ui
    {
    class MainWindow;
    }
    class MainWindow : public QMainWindow
    {
        Q_OBJECT
    public:
        explicit MainWindow(QWidget *parent = 0);
        ~MainWindow();
    private:
        Ui::MainWindow *ui;
        TrafficLightWidget * trafficlight;
    };
    

    mainwindow.cpp

    MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent), ui(new Ui::MainWindow)
    {
        ui->setupUi(this);
    
        trafficlight = new TrafficLightWidget(this);
        trafficlight->setGeometry(50,50,100,275);
        trafficlight->show();
    }
    MainWindow::~MainWindow()
    {
        delete ui;
    }
    

    trafficlightwidget.h

    class TrafficLightWidget : public QWidget
    {
        Q_OBJECT
    public:
        explicit TrafficLightWidget(QWidget *parent = 0);
        ~TrafficLightWidget();
    public slots:
        void greenisOn(bool on);
        void yellowisOn(bool on);
        void redisOn(bool on);
    protected:
        void paintEvent(QPaintEvent * paint);
    private:
        TrafficLightWidget *ui;
        LightWidget *red;
        LightWidget *yellow;
        LightWidget *green;
        QVBoxLayout *vbox;
    };
    

    trafficlightwidget.cpp

    TrafficLightWidget::TrafficLightWidget(QWidget *parent) : QWidget(parent)
    {
        vbox = new QVBoxLayout(this);
        red = new LightWidget(Qt::red, this);
        yellow = new LightWidget(Qt::yellow, this);
        green = new LightWidget(Qt::green, this);
    
        vbox->addWidget(red);
        vbox->addWidget(yellow);
        vbox->addWidget(green);
    
        QPalette pal = this->palette();
        pal.setColor(QPalette::Background, Qt::black);
        this->setPalette(pal);
        this->setAutoFillBackground(true);
    }
    TrafficLightWidget::~TrafficLightWidget()
    {
    
    }
    void TrafficLightWidget::greenisOn(bool on)
    {
        if (on == true)
        {
            green->turnOn();
        }
        else
        {
            green->turnOff();
        }
    }
    void TrafficLightWidget::yellowisOn(bool on)
    {
        if (on == true)
        {
            yellow->turnOn();
        }
        else
        {
            yellow->turnOff();
        }
    }
    void TrafficLightWidget::redisOn(bool on)
    {
        if (on == true)
        {
            red->turnOn();
        }
        else
        {
            red->turnOff();
        }
    }
    void TrafficLightWidget::paintEvent(QPaintEvent *paint)
    {
    
    }
    

    lightwidget.h

    class LightWidget : public QWidget
    {
        Q_OBJECT
        Q_PROPERTY(bool on READ isOn WRITE setOn)
    public:
        explicit LightWidget(const QColor &color, QWidget *parent = nullptr);
        bool isOn();
        void setOn(bool on);
    public slots:
        void turnOff();
        void turnOn();
    protected:
        void paintEvent(QPaintEvent * paint);
    private:
        QColor light_color;
        bool light_on;
    };
    

    lightwidget.cpp

    LightWidget::LightWidget(const QColor &color, QWidget *parent) : QWidget(parent)
    {
        light_color = color;
        light_on = false;
    }
    bool LightWidget::isOn()
    {
        return light_on;
    }
    void LightWidget::setOn(bool on)
    {
        if (on == light_on)
        {
            return;
        }
        light_on = on;
        this->update();
    }
    void LightWidget::turnOff()
    {
        setOn(false);
    }
    void LightWidget::turnOn()
    {
        setOn(true);
    }
    void LightWidget::paintEvent(QPaintEvent *paint)
    {
        if (!light_on)
        {
            return;
        }
    
        QPainter painter(this);
        painter.setRenderHint(QPainter::Antialiasing);
        painter.setBrush(light_color);
        painter.drawEllipse(0, 0, width(), height());
    }
    

    trafficlightcontroller.h

    class TrafficLightController : public QObject
    {
        Q_OBJECT
        Q_PROPERTY(bool redOn READ getred WRITE setred NOTIFY redChanged)
        Q_PROPERTY(bool yellowOn READ getyellow WRITE setyellow NOTIFY yellowChanged)
        Q_PROPERTY(bool greenOn READ getgreen WRITE setgreen NOTIFY greenChanged)
    public:
        explicit TrafficLightController(QObject *parent = nullptr);
        bool getred();
        bool getgreen();
        bool getyellow();
        void setred(bool on);
        void setgreen(bool on);
        void setyellow(bool on);
    signals:
        void redChanged(bool on);
        void greenChanged(bool on);
        void yellowChanged(bool on);
    private:
        QStateMachine *machine;
        QState *greenState;
        QState *redState;
        QState *yellowState;
        QState *redyellowState;
        QTimer *timer;
        bool green;
        bool red;
        bool yellow;
    };
    

    trafficlightcontroller.cpp

    TrafficLightController::TrafficLightController(QObject *parent) : QObject(parent)
    {
        machine = new QStateMachine(this);
        redState = new QState(machine);
        yellowState = new QState(machine);
        greenState = new QState(machine);
        redyellowState = new QState(machine);
        timer = new QTimer(machine);
    
        green = false;
        red = false;
        yellow = false;
    
        redState->assignProperty(this, "redOn", true);
        redState->assignProperty(this, "yellowOn", false);
        redState->assignProperty(this, "greenOn", false);
        redState->assignProperty(timer, "interval", 2000);
        yellowState->assignProperty(this, "redOn", false);
        yellowState->assignProperty(this, "yellowOn", true);
        yellowState->assignProperty(this, "greenOn", false);
        yellowState->assignProperty(timer, "interval", 2000);
        greenState->assignProperty(this, "redOn", false);
        greenState->assignProperty(this, "yellowOn", false);
        greenState->assignProperty(this, "greenOn", true);
        greenState->assignProperty(timer, "interval", 2000);
        redyellowState->assignProperty(this, "redOn", true);
        redyellowState->assignProperty(this, "yellowOn", true);
        redyellowState->assignProperty(this, "greenOn", false);
        redyellowState->assignProperty(timer, "interval", 2000);
    
        redState->addTransition(timer, SIGNAL(timeout()), redyellowState);
        redyellowState->addTransition(timer, SIGNAL(timeout()), greenState);
        greenState->addTransition(timer, SIGNAL(timeout()), yellowState);
        yellowState->addTransition(timer, SIGNAL(timeout()), redState);
    
        machine->setInitialState(redState);
    
        machine->start();
    
        timer->start();
    }
    void TrafficLightController::setred(bool on)
    {
        if (red != on)
        {
            red = on;
            emit redChanged(on);
        }
    }
    void TrafficLightController::setgreen(bool on)
    {
        if (green != on)
        {
            green = on;
            emit greenChanged(on);
        }
    }
    void TrafficLightController::setyellow(bool on)
    {
        if (yellow != on)
        {
            yellow = on;
            emit yellowChanged(on);
        }
    }
    bool TrafficLightController::getred()
    {
        return red;
    }
    
    bool TrafficLightController::getgreen()
    {
        return green;
    }
    
    bool TrafficLightController::getyellow()
    {
        return yellow;
    }
    
    1 Reply Last reply
    0
    • mrjjM Offline
      mrjjM Offline
      mrjj
      Lifetime Qt Champion
      wrote on last edited by
      #2

      Hi

      when you use TrafficLightWidget in main window, do you remember to hook it up to a TrafficLightController ?
      Like show in main.cpp ?

       QObject::connect(&tlc, SIGNAL(greenChanged(bool)), &tl, SLOT(greenisOn(bool)));
       QObject::connect(&tlc, SIGNAL(yellowChanged(bool)), &tl, SLOT(yellowisOn(bool)));
       QObject::connect(&tlc, SIGNAL(redChanged(bool)), &tl, SLOT(redisOn(bool)));
      
      1 Reply Last reply
      1
      • T Offline
        T Offline
        Tobias89
        wrote on last edited by
        #3

        What do you mean exactly?

        I have already tried to update mainwindow as well as trafficlightwidget with this 3 signals.

        mrjjM 1 Reply Last reply
        0
        • T Tobias89

          What do you mean exactly?

          I have already tried to update mainwindow as well as trafficlightwidget with this 3 signals.

          mrjjM Offline
          mrjjM Offline
          mrjj
          Lifetime Qt Champion
          wrote on last edited by
          #4

          @Tobias89

          That the code shown des not seems to connect but i could have missed it.

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

          no controller and no connects. ?

          1 Reply Last reply
          1
          • T Offline
            T Offline
            Tobias89
            wrote on last edited by
            #5

            I have tried to connect it in main.cpp and in the constructor of mainwindow.cpp.
            (This lines are not shown in the above code)
            But it didn't work.

            I tried:
            QObject::connect(&tlc, SIGNAL(lightChanged()), &tl, SLOT(repaint()));
            QObject::connect(&tlc, SIGNAL(lightChanged()), &tl, SLOT(update()));
            QObject::connect(&tlc, SIGNAL(lightChanged()), &tl, SLOT(show()));

            mrjjM 1 Reply Last reply
            0
            • T Tobias89

              I have tried to connect it in main.cpp and in the constructor of mainwindow.cpp.
              (This lines are not shown in the above code)
              But it didn't work.

              I tried:
              QObject::connect(&tlc, SIGNAL(lightChanged()), &tl, SLOT(repaint()));
              QObject::connect(&tlc, SIGNAL(lightChanged()), &tl, SLOT(update()));
              QObject::connect(&tlc, SIGNAL(lightChanged()), &tl, SLOT(show()));

              mrjjM Offline
              mrjjM Offline
              mrjj
              Lifetime Qt Champion
              wrote on last edited by
              #6

              @Tobias89

              When you tried in constructor, did you remember to new the TrafficLightController also ?

              if you did
              TrafficLightController tlc;

              it would be deleted as soon as main window constructor was finished.

              the code from main.cpp can not just be copied to main window.
              The objects need to be NEW.ed.

              1 Reply Last reply
              1
              • T Offline
                T Offline
                Tobias89
                wrote on last edited by
                #7

                In the constructor of mainwindow I tried this version:

                TrafficLightController * controller = new TrafficLightController();
                connect(controller, SIGNAL(lightChanged()), this, SLOT(repaint()));
                connect(controller, SIGNAL(lightChanged()), this, SLOT(update()));
                connect(controller, SIGNAL(lightChanged()), this, SLOT(show()));

                mrjjM 1 Reply Last reply
                0
                • T Tobias89

                  In the constructor of mainwindow I tried this version:

                  TrafficLightController * controller = new TrafficLightController();
                  connect(controller, SIGNAL(lightChanged()), this, SLOT(repaint()));
                  connect(controller, SIGNAL(lightChanged()), this, SLOT(update()));
                  connect(controller, SIGNAL(lightChanged()), this, SLOT(show()));

                  mrjjM Offline
                  mrjjM Offline
                  mrjj
                  Lifetime Qt Champion
                  wrote on last edited by mrjj
                  #8

                  @Tobias89

                  but in original it was greenisOn(bool)

                  is that the same as some widget update ???

                  in original its from

                  TrafficLightController to the TrafficLightWidget ?

                  should that still not be the case???

                  1 Reply Last reply
                  0
                  • T Offline
                    T Offline
                    Tobias89
                    wrote on last edited by
                    #9

                    Now I tried this versions in mainwindow constructor.

                    controller = new TrafficLightController();
                    connect(controller, SIGNAL(lightChanged()), trafficlight, SLOT(repaint()));
                    connect(controller, SIGNAL(lightChanged()), trafficlight, SLOT(update()));
                    connect(controller, SIGNAL(greenChanged(bool)), trafficlight, SLOT(greenisOn(bool)));

                    green = new LightWidget(Qt::green);
                    red = new LightWidget(Qt::red);
                    yellow = new LightWidget(Qt::yellow);
                    connect(controller, SIGNAL(lightChanged()), red, SLOT(repaint()));
                    connect(controller, SIGNAL(lightChanged()), green, SLOT(update()));
                    connect(controller, SIGNAL(lightChanged()), yellow, SLOT(greenisOn(bool)));
                    
                    1 Reply Last reply
                    0
                    • mrjjM Offline
                      mrjjM Offline
                      mrjj
                      Lifetime Qt Champion
                      wrote on last edited by
                      #10

                      Hi

                      The only difference from main should be.

                      TrafficLightWidget tl = new TrafficLightWidget ;
                      TrafficLightController tlc =new TrafficLightController;
                      
                      QObject::connect(tlc, SIGNAL(greenChanged(bool)), tl, SLOT(greenisOn(bool)));
                      QObject::connect(tlc, SIGNAL(yellowChanged(bool)), tl, SLOT(yellowisOn(bool)));
                      QObject::connect(tlc, SIGNAL(redChanged(bool)), &tl, SLOT(redisOn(bool)));
                      

                      unless you change some other code. ??

                      If it could paint by itself in main.cpp
                      there should be no need to connect to update/repaint even if you
                      now do it in main window. It works the same regardless of what
                      it is put into.

                      1 Reply Last reply
                      0
                      • Pablo J. RoginaP Offline
                        Pablo J. RoginaP Offline
                        Pablo J. Rogina
                        wrote on last edited by
                        #11

                        @Tobias89 I took traffic light example and using Qt Creator created default new project (Qt Widgets Application) and added individual Qt classes (LightWidget, TrafficLightWidget and TrafficLight, all based on QWidget). So far it should be pretty much what I imagine you have done.

                        Then I used Qt Creator to edit the only form in the project (mainwindow.ui) and added a Widget object from component palette (section Containers). The magic now is to promote that QWidget into the TrafficLight class, and that's it. No need to do anything else in main.cpp. Please see mine below, no references to any widget, as the TrafficLight component is encapsulated into QMainWindow (because you added it with the form designer)

                        #include "mainwindow.h"
                        #include <QApplication>
                        
                        int main(int argc, char *argv[])
                        {
                            QApplication a(argc, argv);
                            MainWindow w;
                            w.show();
                        
                            return a.exec();
                        }
                        

                        You may have more info about Integrating a Custom Widget into Qt Designer here.

                        Upvote the answer(s) that helped you solve the issue
                        Use "Topic Tools" button to mark your post as Solved
                        Add screenshots via postimage.org
                        Don't ask support requests via chat/PM. Please use the forum so others can benefit from the solution in the future

                        1 Reply Last reply
                        2
                        • T Offline
                          T Offline
                          Tobias89
                          wrote on last edited by
                          #12

                          To promote is the correct keyword, I think.
                          But it still didn't refresh, when a light changes.

                          1 Reply Last reply
                          0
                          • Pablo J. RoginaP Offline
                            Pablo J. RoginaP Offline
                            Pablo J. Rogina
                            wrote on last edited by
                            #13

                            @Tobias89 this project is working fine for me, Qt 5.9.1 / lubuntu 17.10 (Virtualbox VM)

                            Upvote the answer(s) that helped you solve the issue
                            Use "Topic Tools" button to mark your post as Solved
                            Add screenshots via postimage.org
                            Don't ask support requests via chat/PM. Please use the forum so others can benefit from the solution in the future

                            1 Reply Last reply
                            3
                            • T Offline
                              T Offline
                              Tobias89
                              wrote on last edited by
                              #14

                              @Pablo-J-Rogina
                              Thanks a lot!!
                              This works fantastic! :-)

                              1 Reply Last reply
                              0

                              • Login

                              • Login or register to search.
                              • First post
                                Last post
                              0
                              • Categories
                              • Recent
                              • Tags
                              • Popular
                              • Users
                              • Groups
                              • Search
                              • Get Qt Extensions
                              • Unsolved