首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >QMessageBox停止QTimer

QMessageBox停止QTimer
EN

Stack Overflow用户
提问于 2013-02-03 19:00:10
回答 1查看 1.3K关注 0票数 0

我创建了一个QMessageBox实例,在连接到QTimer signal timeout()的插槽中有一个"OK“按钮,并使用exec函数显示它,似乎计时器停止工作,直到按钮按下,盒子关闭。我期望exec创建本地事件循环并发送计时器消息,但是计时器被暂停(没有发出信号timeout() )。有人能解释吗?对不起,我的英语。

更新:示例代码:

代码语言:javascript
复制
#include "mainwindow.h"
#include "ui_mainwindow.h"

MainWindow::MainWindow(QWidget *parent) :
      QMainWindow(parent),
      ui(new Ui::MainWindow)
{
  ui->setupUi(this);
  QTimer *tm1=new QTimer(this),
  *tm2=new QTimer(this);

  connect(tm1,SIGNAL(timeout()),this,SLOT(tslot1()));
  connect(tm2,SIGNAL(timeout()),this,SLOT(tslot2()));
  tm1->start(1000);
  tm2->start(1000);
}

void MainWindow::tslot1(void)
{
  static int cnt;
  qWarning(QString("slot 1 called %1 time(s)").arg(++cnt).toAscii().data());
}

void MainWindow::tslot2(void)
{
  static int cnt;
  qWarning(QString("slot 2 called %1 time(s)").arg(++cnt).toAscii().data());
  if (3==cnt)
  {
    QMessageBox *mb=new QMessageBox(QMessageBox::Critical,tr("Error"),tr("tm2 halted !"),QMessageBox::Ok,this);
    mb->exec();
  }
}

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

回答 1

Stack Overflow用户

发布于 2013-02-03 23:39:01

您可以看到事件循环正在运行,因为timer1正在触发超时。从文档中可以看到,exec()阻塞了调用,因此它将阻塞调用方函数(QTimer时隙),直到对话框关闭。

这就引出了QObject源代码。执行插槽功能后,在QMetaObject::activate中,最后一步是重置信号的发送方:

QObjectPrivate::resetCurrentSender(receiver, &currentSender, previousSender);

这将重置QTimer状态,并将再次开始倒计时。我认为这是确保在大多数UI库中按顺序调用定时器回调的常识方法,而不是在相同的计时器中并行调用。

因为exec()会阻止计时器回调,所以QTimer不会被重置,回调也不会再次被调用(直到函数恢复,QTimer得到它的重置)。

您有几种处理此问题的方法:

1)如果您不想阻止您的函数,并且不需要模态对话框的结果来继续进行函数--调用QMessageBox::open()而不是QMessageBox::exec() --它将不会阻塞调用函数。

2)如果您需要对话框的结果来继续这个函数,并且您不想停止您的计时器回调,那么简单的方法是在输入回调函数时通过依次调用QTimerQTimer::start()来手动重置QTimer::stop()QTimer::start()

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/14676085

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档