0

所以我正在编写一个程序,显示一个单词的每个字母 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";
}
4

3 回答 3

2

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

主文件

#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();
}

主程序

TEMPLATE = app
TARGET = main
QT = core
CONFIG += c++11
SOURCES += main.cpp

构建并运行

qmake && make && ./main

输出

apple
于 2014-12-07T11:17:26.073 回答
0

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

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

你也可以使用QTimer和连接QTimer::timeout()信号来完成同样的事情。

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

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

于 2014-12-07T11:21:05.010 回答
0

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

于 2014-12-07T18:16:23.073 回答