Search code examples
c++qtqtcoreqt-signalsqtimer

Substitute for sleep function in Qt/C++


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";
}

Solution

  • 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