【问题标题】:Why is the Qt event loop left为什么Qt事件循环离开了
【发布时间】:2016-10-21 12:37:36
【问题描述】:

我想要一个执行以下操作的小程序:

  1. 启动单次 QTimer
  2. 超时时,会显示一个 QMessageBox
  3. 如果单击“继续”按钮,则会关闭该框并重新启动计时器
  4. 如果单击“停止”按钮,则会关闭框并退出应用程序

我遇到的问题是,一旦我隐藏消息框,事件循环就会离开。该框仅显示一次。我在控制台版本中复制了我的程序,它按预期运行。这是我的代码。提前感谢您的帮助。

ma​​in.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);
}

【问题讨论】:

    标签: qt event-loop qmessagebox


    【解决方案1】:

    创建的计时器被设置为singleshot,它已经调用了timeout

    如果您查看QTimer source codestart() 的调用,您会看到它声明:-

    如果 singleShot 为 true,则计时器将只激活一次。

    您可以使用类函数QTimer::singleShot 修复和简化代码

    【讨论】:

    • 感谢您的回答。我相信问题不在于单次计时器,因为我可以基于相同的计时器原理运行控制台程序。一旦按下“继续”按钮,计时器就会重新启动,我希望程序继续运行。它没有做什么。
    猜你喜欢
    • 2017-04-14
    • 1970-01-01
    • 2018-06-16
    • 1970-01-01
    • 2016-04-21
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多