0

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";
}
László Papp
  • 51,870
  • 39
  • 111
  • 135
Armand Maree
  • 488
  • 2
  • 6
  • 21
  • Yes, repeating QTimer. – László Papp Dec 07 '14 at 11:12
  • 1
    Look [here](http://stackoverflow.com/questions/18764094/how-to-sleep-pause-in-qt) for some hints. – BaCaRoZzo Dec 07 '14 at 11:15
  • I looked at that question and I updated my code but the connect function does not seem to connect the signal and slot. (I posted the code). Sorry for taking so long, our power went out. – Armand Maree Dec 07 '14 at 16:27
  • 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 combining class1 and the timer class. Doesn't make sense to me, but it works. – Armand Maree Dec 07 '14 at 18:05

3 Answers3

2

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
László Papp
  • 51,870
  • 39
  • 111
  • 135
  • I looked at your suggestion and I updated my code but the connect function does not seem to connect the signal and slot. (I posted the code). Sorry for taking so long, our power went out. – Armand Maree Dec 07 '14 at 16:28
  • @Ipapp I tried to, but it only works when I use it in the main.cpp. And in this program I can't use it there, I use it when a button is pressed. – Armand Maree Dec 07 '14 at 16:33
  • @Ravenblack: sorry, but you have not given us any evidence why that would not work. 1) Rerun qmake 2) Check return value of the connect 3) Check if the signal is emitted at all. – László Papp Dec 07 '14 at 16:35
  • @Ipapp, I did as you said: `qDebug()< – Armand Maree Dec 07 '14 at 16:46
  • @Ravenblack: cannot reproduce your problem, I am afraid. Please make sure that you provide a main.cpp on its own that reproduces the problem. I am sure that the problem is somewhere that you have not shown to us. – László Papp Dec 07 '14 at 16:53
  • 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. I could not reproduce the problem with just the main.cpp, but if I created a separate project with the 2 classes, it seems like the problem persists. Thanks for your help anyway. – Armand Maree Dec 07 '14 at 18:08
0

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.

ezaquarii
  • 1,914
  • 13
  • 15
0

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.

Armand Maree
  • 488
  • 2
  • 6
  • 21
  • Perhaps you need to run qmake again to ensure that the new class is being processed properly by MOC. MOC helps in making the signals and slots work. Also, you should check the return code from connect(). – Hamish Moffatt Dec 08 '14 at 00:55