0
votes

I am building a little program that shows traffic light images using QTimer. So i setup my timer and everything works good. But I cant figure out, how can I get the Robot Lights to ->show() and ->hide() each time the timer interval is reached. I can have this all wrong, im still learning so please advise.

mainwindow.h

 #ifndef MAINWINDOW_H
#define MAINWINDOW_H

#include <QMainWindow>
#include<QTimer>

namespace Ui {
class MainWindow;
}

class MainWindow : public QMainWindow
{
    Q_OBJECT

public:
    explicit MainWindow(QWidget *parent = 0);
    ~MainWindow();
    void timer();
    QTimer *mytimer;



private:
    Ui::MainWindow *ui;
    int timerValue;

private slots:
    void showGreen();
    void showYellow();
    void showRed();
    void on_startButton_clicked();

};

#endif // MAINWINDOW_H

mainwindow.cpp

#include "mainwindow.h"
#include "ui_mainwindow.h"

MainWindow::MainWindow(QWidget *parent) :
    QMainWindow(parent),
    ui(new Ui::MainWindow)
{
    ui->setupUi(this);
   ui->green->setVisible(false);
    ui->yellow->setVisible(false);
     ui->red->setVisible(false);
}

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

void MainWindow::timer(){
    ui->green->setVisible(true);
    mytimer = new QTimer(this);
    connect(mytimer,SIGNAL(timeout()),this,SLOT(showYellow()));
    mytimer->start(timerValue = (ui->spinBox->value())*1000);

}

void MainWindow::showYellow(){
    ui->yellow->setVisible(true);
    mytimer = new QTimer(this);
    connect(mytimer,SIGNAL(timeout()),this,SLOT(showRed()));
    mytimer->start(timerValue);
}

void MainWindow::showRed(){
   ui->red->setVisible(true);
    mytimer = new QTimer(this);
    connect(mytimer,SIGNAL(timeout()),this,SLOT(showGreen));
    mytimer->start(timerValue);
}
void MainWindow::showGreen(){
    ui->green->setVisible(true);
    mytimer = new QTimer(this);
    connect(mytimer,SIGNAL(timeout()),this,SLOT(showYellow()));
    mytimer->start(timerValue);
}
void MainWindow::on_startButton_clicked()
{
    timer();
    ui->startButton->setEnabled(false);
}

I Also disable the Start button when clicked so the timer cannot run twice.

So On the main Window UI I basicly Have a Spinbox that takes the input of the user which is the time that I pass that to Qtimer, and then I have the 3 images with lights red green yellow that has to show and hide in the intervals . So I created almost something like a manual loop. Qtimer starts and shows Green, then goes to ShowYellow Slot and then showRed slot, so now, its suppose to go to the Green slot and then to yellow, but it doesnt go to Green again.

Can someone tell me why not.

2

2 Answers

1
votes

Read the comments:

MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent), ui(new Ui::MainWindow) {
    ...
    mytimer = new QTimer(this); // create QTimer once
}

void MainWindow::timer() {
    timerValue = ui->spinBox->value() * 1000;

    showGreen(); // reuse showGreen()
}

void MainWindow::showYellow() {
    // this is how toggling can be done
    ui->yellow->setVisible(!ui->yellow->isVisible());

    mytimer->disconnect(); // disconnect before making a new connection
    connect(mytimer ,SIGNAL(timeout()), this, SLOT(showRed()));
    mytimer->start(timerValue);
}

void MainWindow::showRed() {
    ui->red->setVisible(!ui->red->isVisible());

    mytimer->disconnect();
    connect(mytimer ,SIGNAL(timeout()), this, SLOT(showGreen()));
    mytimer->start(timerValue);
}

void MainWindow::showGreen() {
    ui->green->setVisible(!ui->green->isVisible());

    mytimer->disconnect();
    connect(mytimer ,SIGNAL(timeout()), this, SLOT(showYellow()));
    mytimer->start(timerValue);
}
0
votes

Perhaps most simply:

void MainWindow::showHide(){
    ui->green->setVisible(!ui->green->isVisible());
}

The show() and hide() member functions of QWidget are equivalent to setVisible(true) and setVisible(false), respectively.

A problem you may run into later, if you press the start button more than once, is that you spawn a new interval timer every time, leading to quicker blinking with every press of the button. If this is not what you want to happen, you'll have to control the generation of new timers.