Запускать другое событие при сбросе QTimer

Я создаю небольшую программу, которая показывает изображения светофора с использованием QTimer. Итак, я установил свой таймер, и все работает хорошо. Но я не могу понять, как я могу заставить роботы светиться -> show () и -> hide () каждый раз, когда достигается интервал таймера. Я могу ошибаться, я все еще учусь, поэтому, пожалуйста, посоветуйте.

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);
}

Я также отключаю кнопку «Пуск» при нажатии, чтобы таймер не запускался дважды.

Итак, в главном пользовательском интерфейсе окна у меня в основном есть Spinbox, который принимает ввод пользователя, который является временем, когда я передаю его Qtimer, а затем у меня есть 3 изображения с красным, зеленым, желтым светом, которые должны показывать и скрывать в интервалах . Так что я создал что-то вроде ручного цикла. Qtimer запускается и показывает зеленый цвет, затем переходит в слот ShowYellow, а затем слот showRed, поэтому теперь предполагается, что он перейдет в слот Green, а затем желтый, но он снова не переходит в зеленый.

Может кто-нибудь подскажет, почему бы и нет.


person Vaaljan    schedule 14.03.2015    source источник


Ответы (2)


Прочтите комментарии:

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);
}
person svlasov    schedule 14.03.2015
comment
Я не совсем понимаю, что ты говоришь. Решит ли это мою проблему с отображением и скрытием изображений? или это просто лучшая практика моей программы? - person Vaaljan; 14.03.2015
comment
Наличие нескольких таймеров, вызывающих один и тот же слот, - это не просто плохая практика, это проблема. @Wintermute показал, как можно переключать видимость изображения. - person svlasov; 14.03.2015
comment
Я исправил эту проблему, отключив кнопку, когда пользователь нажимает на нее. согласно заданию, таймер не должен останавливаться, пока не будет закрыт, так что на данный момент это нормально. У меня все еще есть проблема, не могли бы вы оставить комментарий к новому изменению, которое я внес в вопрос / код - person Vaaljan; 14.03.2015
comment
Читайте с комментариями. - person svlasov; 14.03.2015
comment
Вау, большое спасибо. Не знал, что могу создать только один таймер. Но сейчас программа почему-то пропускает желтый. Есть идеи, почему? - person Vaaljan; 15.03.2015

Пожалуй, проще всего:

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

Функции-члены show() и hide() для QWidget эквивалентны setVisible(true) и setVisible(false) соответственно.

Проблема, с которой вы можете столкнуться позже, если вы нажмете кнопку запуска более одного раза, заключается в том, что вы каждый раз создаете новый интервальный таймер, что приводит к более быстрому миганию при каждом нажатии кнопки. Если это не то, что вы хотите, вам придется контролировать создание новых таймеров.

person Wintermute    schedule 14.03.2015