Почему остался цикл событий Qt

Я хочу небольшую программу, делающую следующее:

  1. запустить однократный QTimer
  2. когда время истекает, отображается QMessageBox
  3. если нажата кнопка «Продолжить», окно закрывается и таймер перезапускается
  4. если нажата кнопка "Стоп", окно закрывается и приложение закрывается

У меня проблема в том, что цикл событий остается, как только я скрываю окно сообщения. Коробка отображается только один раз. Я воспроизвел свою программу в консольной версии, и она работает, как и ожидалось. Вот мой код. Заранее спасибо за вашу помощь.

main.c

#include <QtGui/QApplication>
#include "TimedDialog.h"

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

  TimedDialog dialog(&app, SLOT(quit()));
  dialog.run();

  return app.exec();
}

TimedDialog.h

#ifndef TIMED_DIALOG_H
#define TIMED_DIALOG_H

#include <QObject>
#include <QTimer>

class QMessageBox;
class QPushButton;
class QAbstractButton;

class TimedDialog : public QObject
{
  Q_OBJECT

public:
  TimedDialog(
    QObject const * receiver,
    char const * method);

  ~TimedDialog();

  void run(void);

signals:
  void stop(void);

private:
  QMessageBox* _box;
  QPushButton* _buttonContinue;
  QPushButton* _buttonStop;
  QTimer _timer;

  static int const DELAY = 2 * 1000; // [ms]

private slots:
  void onTimeout(void);
  void onButtonClicked(QAbstractButton * button);
};

#endif

TimedDialog.cpp

#include <assert.h>
#include <QMessageBox>
#include <QPushButton>

#include "TimedDialog.h"

TimedDialog::TimedDialog(
  QObject const * receiver,
  char const * method)
  : QObject(),
  _box(0),
  _buttonContinue(0),
  _buttonStop(0),
  _timer()
{
  _box = new QMessageBox();
  _box->setWindowModality(Qt::NonModal);
  _box->setText("Here is my message!");

  _buttonContinue = new QPushButton("Continue");
  _box->addButton(_buttonContinue, QMessageBox::AcceptRole);

  _buttonStop = new QPushButton("Stop");
  _box->addButton(_buttonStop, QMessageBox::RejectRole);

  _timer.setSingleShot(true);

  assert(connect(&_timer, SIGNAL(timeout()), this, SLOT(onTimeout())));
  assert(connect(_box, SIGNAL(buttonClicked(QAbstractButton *)), this, SLOT(onButtonClicked(QAbstractButton *))));
  assert(connect(this, SIGNAL(stop()), receiver, method));
}

TimedDialog::~TimedDialog()
{
  delete _box;
}

void TimedDialog::onTimeout(void)
{
  _box->show();
}

void TimedDialog::onButtonClicked(QAbstractButton * button)
{
  _box->hide();

  if (button == _buttonContinue)
  {
    _timer.start(DELAY);
  }
  else
  {
    emit stop();
  }
}

void TimedDialog::run(void)
{
  _timer.start(DELAY);
}

person Dams    schedule 21.10.2016    source источник


Ответы (1)


Созданный таймер устанавливается как singleshot, который уже вызвал timeout.

Если вы посмотрите на QTimer исходный код для вызова start() вы можете видеть, что он гласит: -

Если singleShot равно true, таймер будет активирован только один раз.

Вы можете исправить и упростить код с помощью функции класса QTimer::singleShot.

person TheDarkKnight    schedule 21.10.2016
comment
Спасибо за Ваш ответ. Я считаю, что проблема не в таймере одиночного выстрела, потому что я могу запустить консольную программу, основанную на том же принципе таймера. После нажатия кнопки «Продолжить» таймер перезапускается, и я ожидаю, что программа продолжит работу. Чего он не делает. - person Dams; 25.10.2016