问题
I need some help on the usage of Qtimer.
I work with Qt 5.0.2 and here my problem :
I am trying to develop a Timer, and the interface is simple :
There is just 2 button : the button "Start", to launch the timer, and the "Pause" Button, and a QtimeEdit to display the time.
This screenshot shows how it looks like : http://img834.imageshack.us/img834/1046/5ks6.png
The problem is that the pause function doesn't work. I have read all the documentation about Qtimer here : http://harmattan-dev.nokia.com/docs/library/html/qt4/qtimer.html and here : qt.developpez.com/doc/5.0-snapshot/qtimer/ , but no result.
This is the source code I have : (I put only what is needed)
// 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();
}
}
When I push the Start button, the timer starts well, but when I push "Pause" it only pause it on the graphic interface, but when I resume, it shows the present time as if it hadn't paused.
For instance :
I start. I pause at 00:05. It blocks apparently the timer. I wait for 10 seconds. I resume the timer, it shows 00:15 instead of 00:06
How could I fix that ?
Thank you !
EDIT : Thanks Kuba Ober, but could you explain me the code you posted please ?
How does the pause work ?
回答1:
Below is a SSCCE, tested under both Qt 4.8 and 5.1.
//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"
回答2:
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);
}
回答3:
I made a Timer class for the start, stop, pause and resume
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();
}
}
来源:https://stackoverflow.com/questions/18440727/how-to-pause-and-resume-a-qtimer-qt-5