How to pause and resume a Qtimer (Qt 5)
我需要有关Qtimer使用的帮助。
我使用Qt 5.0.2,这是我的问题:
我正在尝试开发一个Timer,并且界面很简单:
只有2个按钮:用于启动计时器的按钮"开始"和"暂停"按钮,以及用于显示时间的QtimeEdit。
此屏幕截图显示了它的外观:http://img834.imageshack.us/img834/1046/5ks6.png
问题是暂停功能不起作用。我在这里阅读了有关Qtimer的所有文档:http://harmattan-dev.nokia.com/docs/library/html/qt4/qtimer.html和此处:qt.developpez.com/doc/5.0-snapshot/qtimer/ ,但没有结果。
这是我拥有的源代码:(我只输入了需要的内容)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 | // Creation of the Buttons and the time area void MainWindow::createBottom() { bottom = new QWidget(); play = new QPushButton("Launch",this); pause = new QPushButton("Pause",this); play->setDisabled(false); pause->setDisabled(true); timeEdit = new QTimeEdit(this); timeEdit->setDisplayFormat("mm:ss"); layout->addWidget(play); layout->addWidget(pause); layout->addWidget(timeEdit ); bottom->setLayout(layout); connect(play, SIGNAL(clicked()), this, SLOT(startSimulation())); connect(pause, SIGNAL(clicked()), this, SLOT(pauseSimulation())); } // to resume the timer where is was stopped void MainWindow::resumeSimulation() { timer->blockSignals( false ); pause->setText("Pause"); pause->disconnect(SIGNAL(clicked())); connect(pause, SIGNAL(clicked()), this, SLOT(pauseSimulation())); paused = false; timer->start(); int timeOfPause = time->restart(); int timeTotal = timeOfPause + timeElapsed; time->addMSecs(-timeTotal); } // to Start the timer void MainWindow::pauseSimulation() { timer->blockSignals(true); pause->setText("Resume"); timer->stop(); play->setDisabled(false); //pause->setDisabled(true); pause->disconnect(SIGNAL(clicked())); connect(pause, SIGNAL(clicked()), this, SLOT(resumeSimulation())); paused = true; } // to Start the timer from zero. void MainWindow::startSimulation() { timer = new QTimer(this); connect(timer, SIGNAL(timeout()), this , SLOT(updateTime())); timer->start(500); play->setDisabled(true); pause->setDisabled(false); } void MainWindow::updateTime() { if(time == NULL) { time = new QTime(0,0,0,0); time->start(); } //timeEdit->setTime(QTime::fromS(time->elapsed())); //time = &(time->addMSecs(1000)); if(hasRestart) { time->restart(); time->addMSecs(-timeElapsed); hasRestart = false; } else { timeElapsed =+ time->elapsed(); } int seconds = 0; int minutes = 0; int hours = 0; if(!paused) { seconds = (timeElapsed/1000)%60; minutes = (timeElapsed/60000)%60; hours = (timeElapsed/3600000)%24; std::cout <<"Test :" << hours <<":" << minutes <<":" << seconds << std::endl; timeEdit->setTime(QTime(0,minutes,seconds,0)); timeEdit->update(); } } |
当我按下"开始"按钮时,计时器会很好地启动,但是当我按下"暂停"时,它只会在图形界面上将其暂停,但是当我恢复时,它将显示当前时间,好像没有已暂停。
例如:
我开始。
我在00:05暂停。它显然阻塞了计时器。
我等待10秒钟。我恢复计时器,它显示00:15而不是00:06
我该如何解决?
谢谢!
编辑:感谢库巴·奥伯(Kuba Ober),但能否请您向我解释您发布的代码?
暂停如何工作?
以下是SSCCE,已在Qt 4.8和5.1下进行了测试。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 | //main.cpp #include <QApplication> #include <QPushButton> #include <QVBoxLayout> #include <QLabel> #include <QElapsedTimer> #include <QTime> class Window : public QWidget { Q_OBJECT int m_timerId; qint64 m_accumulator; QLabel *m_label; QElapsedTimer m_timer; Q_SLOT void on_restart_clicked() { m_accumulator = 0; m_timer.restart(); if (m_timerId == -1) m_timerId = startTimer(50); } Q_SLOT void on_pause_clicked() { if (m_timer.isValid()) { m_accumulator += m_timer.elapsed(); m_timer.invalidate(); } else { m_timer.restart(); m_timerId = startTimer(50); } } void timerEvent(QTimerEvent * ev) { if (ev->timerId() != m_timerId) { QWidget::timerEvent(ev); return; } QTime t(0,0); t = t.addMSecs(m_accumulator); if (m_timer.isValid()) { t = t.addMSecs(m_timer.elapsed()); } else { killTimer(m_timerId); m_timerId = -1; } m_label->setText(t.toString("h:m:ss.zzz")); } public: explicit Window(QWidget *parent = 0, Qt::WindowFlags f = 0) : QWidget(parent, f), m_timerId(-1) { QVBoxLayout * l = new QVBoxLayout(this); QPushButton * restart = new QPushButton("Start"); QPushButton * pause = new QPushButton("Pause/Resume"); restart->setObjectName("restart"); pause->setObjectName("pause"); m_label = new QLabel("--"); l->addWidget(restart); l->addWidget(pause); l->addWidget(m_label); QMetaObject::connectSlotsByName(this); } }; int main(int argc, char *argv[]) { QApplication a(argc, argv); Window w; w.show(); return a.exec(); } #include"main.moc" |
我为启动,停止,暂停和恢复设置了Timer类。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 | class MyTimer { public: MyTimer(); QTime m_qtime; int m_accumulator; void start(); int stop(); void pause(); void resume(); }; MyTimer::MyTimer() :m_accumulator(0), m_qtime(QTime()) { } void MyTimer::start() { m_qtime.start(); m_accumulator = 0; } int MyTimer::stop() { if(!m_qtime.isNull()) { int l_elapsedTime = m_qtime.elapsed(); m_accumulator += l_elapsedTime; } m_qtime = QTime(); return m_accumulator; } void MyTimer::pause() { if(!m_qtime.isNull()) { int l_elapsedTime = m_qtime.elapsed(); m_accumulator += l_elapsedTime; } } void MyTimer::resume() { if(!m_qtime.isNull()) { m_qtime.restart(); } } |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 | QTime totalTime, sinceStart; void MainWindow::createBottom() { bottom = new QWidget(); play = new QPushButton("Launch",this); pause = new QPushButton("Pause",this); play->setDisabled(false); pause->setDisabled(true); timeEdit = new QTimeEdit(this); timeEdit->setDisplayFormat("mm:ss"); layout->addWidget(play); layout->addWidget(pause); layout->addWidget(timeEdit); bottom->setLayout(layout); connect(play, SIGNAL(clicked()), this, SLOT(startSimulation())); connect(pause, SIGNAL(clicked()), this, SLOT(pauseSimulation())); connect(this, SIGNAL(timeChanged(QTime)), timeEdit, SLOT(setTime(QTime))); timer = new QTimer(this); connect(timer, SIGNAL(timeout()), this , SLOT(updateTime())); } void MainWindow::updateTime() { emit timeChanged(totalTime.addMSecs(sinceStart.elpased())); } void MainWindow::resumeSimulation() { sinceStart.restart(); timer->start(); } void MainWindow::pauseSimulation() { timer->stop(); totalTime = totalTime.addMSecs(sinceStart.restart()); emit timeChanged(totalTime); } |