2013-08-26 174 views
3

我需要Qtimer的使用方面的一些帮助。如何暂停和恢复Qtimer(Qt 5)

我使用Qt 5.0.2,在这里我的问题的工作:

我试图建立一个定时器,界面很简单:

只是有2按钮:在“开始”按钮,启动计时器,“暂停”按钮,以及QtimeEdit来显示时间。

此屏幕快照显示它的样子:http://img834.imageshack.us/img834/1046/5ks6.png

的问题是,暂停功能不能正常工作。我已阅读所有有关Qtimer的文档:http://harmattan-dev.nokia.com/docs/library/html/qt4/qtimer.html和here:qt.developpez.com/doc/5.0-snapshot/qtimer/,但没有结果。

这是源代码,我有:(我只放所需要的)

// 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

我该如何解决这个问题?

谢谢!

编辑:谢谢库巴奥伯,但你能解释我的代码吗?

暂停是如何工作的?

+0

不,你没有把只在所需的内容。你只会把你认为**所需要的东西放进去。 – Greenflow

+0

为什么每次开始模拟时都会创建一个新的'QTimer'对象? 'timeElapsed'在哪里得到它的价值? – thuga

+0

在你的代码中有很多问题,但最重要的问题是你没有显示的'updateTime()'插槽。 –

回答

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

Marek R:我得到:qt错误c3861'timeChanged'标识符未找到 – user2717381

+0

@ user2717381您是否在'MainWindow.h'中声明了该信号? – thuga

+0

不。它应该如何? void timeChanged(Qtime & t);? – user2717381

6

下面是一个SSCCE,下Qt的4.8和5.1这两个测试。

Screenshot of the example

//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" 
+1

SSCCE已成为有史以来最不易读的首字母缩写,但我确实喜欢这个主意。 –

0

我做了一个Timer类的启动,停止,暂停和恢复

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