问题
So I am writing a program that displays each letter of a word for 1 second with a 1 second interval between the letters. (It's for a spelling exercise for grade 1). I am currently using the sleep function to "pause" the program for 1 second before it "updates" again. After that it displays the word for a second and then removes it. I repaint before the sleep function, else it does not seem to update in time.
Here is the basic function:
QString word = "apple";
QThread thread;
for(int i = 0; i < word.size(); i++)
{
ui->label1->setText(word[i]);
ui->label1->repaint();
thread.sleep(1);
ui->label1->setText("");
thread.sleep(1);
}
ui->label1->setText(word);
ui->label1->repaint();
thread.sleep(1);
ui->label1->setText("");
This works fine, except the program stops responding (even though I can see the correct output is still displaying) until the whole function is done executing then it works fine again. Is there another way I can accomplish this goal without using sleep? I am quite new to Qt.
Update I made. I made a new class that will handle the timer, but it does not seem to actually connect the signal and slot. Here is the .h file:
#ifndef TIMERDISPLAY_H
#define TIMERDISPLAY_H
#include <QTimer>
#include <QObject>
class TimerDisplay:public QObject
{
Q_OBJECT
public:
TimerDisplay();
public slots:
void expired();
private:
QTimer timer;
};
#endif // TIMERDISPLAY_H
and the .cpp file:
#include "timerdisplay.h"
#include <QDebug>
TimerDisplay::TimerDisplay()
{
connect(&timer, SIGNAL(timeout()), this, SLOT(expired()));
timer.setSingleShot(false);
timer.setInterval(1000);
timer.start();
}
void TimerDisplay::expired()
{
qDebug()<<"timer expired";
}
回答1:
Use QTimer or QElapsedTimer if you need more precision.
main.cpp
#include <QTimer>
#include <QCoreApplication>
#include <QString>
#include <QTextStream>
#include <QDebug>
int main(int argc, char **argv)
{
QCoreApplication application(argc, argv);
QTimer timer;
QTextStream textStream(stdout);
QString word = "apple";
int i = 0;
QObject::connect(&timer, &QTimer::timeout, [&textStream, word, &i] () {
if (i < word.size()) {
textStream << word.at(i) << flush;
++i;
}
});
timer.start(1000);
return application.exec();
}
main.pro
TEMPLATE = app
TARGET = main
QT = core
CONFIG += c++11
SOURCES += main.cpp
Build and Run
qmake && make && ./main
Output
apple
回答2:
This is happening, because you're blocking the thread. In most cases you're interested in using event loop.
You can use timer and increment a counter in a slot function. Every QObject
has support for timer. You can start it using int QObject::startTimer(int interval)
and it will call virtual void timerEvent(QTimerEvent *event)
every interval
miliseconds (it's a virtual method - reimplement it).
You can also use QTimer
and connect QTimer::timeout()
signal to accomplish the same thing.
Inside timer handler increment a counter and print the character.
It's a good idea to put your hands on finite state machine concept. FSMs are a great tool for solving similar problems problems. In fact, using a timer callback you create a state machine, but very simple one.
回答3:
I still don't know what the problem is, but I found a make-shift solution. In my program I include one class (eg class1) into my mainwindow.cpp and from that class I include the timer class. I solved the problem by removing the timer class and adding all those functions to class1. Doesn't make sense to me, but it works.
来源:https://stackoverflow.com/questions/27341944/substitute-for-sleep-function-in-qt-c