在Qt / C ++中替代睡眠功能

时间:2014-12-07 11:01:33

标签: c++ qt qtcore qt-signals qtimer

所以我正在编写一个程序,显示一个单词的每个字母1秒,字母之间间隔1秒。 (它用于1年级的拼写练习)。我目前正在使用睡眠功能来暂停"程序在它之前1秒钟更新"再次。之后,它会显示该单词一秒钟,然后将其删除。我在睡眠功能之前重新绘制,否则它似乎没有及时更新。

这是基本功能:

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

这个工作正常,除了程序停止响应(即使我可以看到正确的输出仍然显示),直到整个功能完成执行然后它再次正常工作。有没有其他方法可以在不使用睡眠的情况下实现这一目标?我是Qt的新手。

我做的更新。我创建了一个新的类来处理定时器,但它似乎并没有实际连接信号和插槽。这是.h文件:

#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

和.cpp文件:

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

3 个答案:

答案 0 :(得分:2)

如果您需要更高的精确度,请使用QTimerQElapsedTimer

的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

构建并运行

qmake && make && ./main

输出

apple

答案 1 :(得分:0)

这种情况正在发生,因为您正在阻止线程。在大多数情况下,您对使用事件循环感兴趣。

您可以使用计时器并在插槽功能中递增计数器。每个QObject都支持计时器。您可以使用int QObject::startTimer(int interval)启动它,它会每隔virtual void timerEvent(QTimerEvent *event)毫秒调用interval(它是一个虚拟方法 - 重新实现它)。

您还可以使用QTimer并连接QTimer::timeout()信号来完成同样的事情。

内部计时器处理程序递增计数器并打印字符。

将手放在有限状态机概念上是一个好主意。 FSM是解决类似问题的好工具。实际上,使用计时器回调可以创建状态机,但非常简单。

答案 2 :(得分:0)

我仍然不知道问题所在,但我找到了一个改变生活的解决方案。在我的程序中,我将一个类(例如class1)包含到我的mainwindow.cpp中,并从该类中包含计时器类。我通过删除计时器类并将所有这些函数添加到class1来解决了这个问题。对我没有意义,但它确实有效。