简体   繁体   English

如何停止 QTimer?

[英]How to stop a QTimer?

So I have a simple class below that uses a QTimer to add a number to the total every 1 second:所以我在下面有一个简单的类,它使用 QTimer 每 1 秒向总数添加一个数字:


// score.h

#include <QObject>
#include <QTimer>

class Score : public QObject
{
    Q_OBJECT
public:
    explicit Score(QObject *parent = nullptr);
    void start();
    void stop();
    QTimer *timer;
    int getScore();

private slots:
    void update();

private:
    int score;

};

// score.cpp

#include "score.h"

Score::Score(QObject *parent) : QObject(parent)
{
    score = 0;
    timer = new QTimer(this);
}

void Score::start()
{
    timer->start(1000);
}

void Score::stop()
{
    timer->stop();
}

int Score::getScore()
{
    return score;
}

void Score::update()
{
    score += 10;
    qDebug() << score;
}

// main.cpp

#include <QCoreApplication>
#include "score.h"
#include <QtDebug>
#include <iostream>

int main(int argc, char *argv[])

{
    QCoreApplication a(argc, argv);

    Score score{};
    std::string input{""};

    while(input!="1") {
        std::cout << "1. to stop" << std::endl;
        std::cout << "2. to start" << std::endl;
        std::cin >> input;

        if(input=="1") {
            score.stop();
        }
        else if(input=="2") {
            score.start();
        }
    }
    return a.exec();
}

During the loop, if I press if my input was 2, nothing is happening.在循环过程中,如果我按输入为 2,则不会发生任何事情。 The slot doesn't seem to fire as I don't see anything that is outputting to the console.该插槽似乎没有触发,因为我没有看到任何输出到控制台的内容。 I am pretty new to QT in general so I may have done something incorrect.总的来说,我对 QT 还是很陌生,所以我可能做错了一些事情。 Another thought I had that it could be due to some threading issues.我的另一个想法是,这可能是由于一些线程问题。 But I haven't had much experience with threading before.但我之前没有太多线程经验。

Your implementation has 2 crucial errors:您的实现有 2 个关键错误:

  • The eventloop is never started since the while loop does not allow it, and if the eventloop is not started then asynchronous elements such as QTimer, signals, etc. will not work. eventloop 永远不会启动,因为 while 循环不允许它,如果 eventloop 没有启动,那么异步元素如 QTimer、信号等将不起作用。

  • Even so, the eventloop will work.即便如此,事件循环仍然有效。 You have not made the connection between the timeout signal with the updata slot.您尚未在超时信号与更新槽之间建立连接。

Considering the above you have to implement the reading of stdin without using a loop and the implementation of the reading will depend on the OS, so to simplify the solution we can use the QConsole library that implements the reading of stdin through signals:考虑到上述情况,您必须在不使用循环的情况下实现 stdin 的读取,并且读取的实现将取决于操作系统,因此为了简化解决方案,我们可以使用QConsole 库通过信号实现 stdin 的读取:

├── 3rdParty
│   └── QConsole
│       ├── Demo
│       │   ├── Demo.pro
│       │   └── main.cpp
│       ├── LICENSE
│       ├── qconsole.cpp
│       ├── qconsole.h
│       ├── qconsole.pri
│       ├── README.md
│       ├── readthread_win.cpp
│       └── readthread_win.h
├── 64746801.pro
├── main.cpp
├── score.cpp
└── score.h

* .pro * .pro

QT -= gui

CONFIG += c++11 console
CONFIG -= app_bundle

SOURCES += \
        main.cpp \
        score.cpp

HEADERS += \
    score.h

include(3rdParty/QConsole/qconsole.pri)

main.cpp主程序

#include <QCoreApplication>
#include <QFile>
#include <QDebug>

#include <qconsole.h>

#include "score.h"

int main(int argc, char *argv[])
{
    QCoreApplication a(argc, argv);

    Score score;

    QConsole console;
    QObject::connect(&console, &QConsole::readyRead, [&](){
        auto data = console.read(console.bytesAvailable());
        if(data == QStringLiteral("1\n")){
            score.stop();
        }
        else if(data == QStringLiteral("2\n")){
            score.start();
        }
    });
    if(!console.open()) {
        qCritical() << console.errorString();
        return EXIT_FAILURE;
    }
    return a.exec();
}

score.h分数.h

#ifndef SCORE_H
#define SCORE_H

#include <QObject>

class QTimer;

class Score : public QObject
{
    Q_OBJECT
public:
    explicit Score(QObject *parent = nullptr);
    void start();
    void stop();
    int getScore();

private slots:
    void update();

private:
    int score;
    QTimer *timer;
};

#endif // SCORE_H

score.cpp分数.cpp

#include "score.h"

#include <QTimer>
#include <QDebug>

Score::Score(QObject *parent) : QObject(parent)
{
    score = 0;
    timer = new QTimer(this);
    connect(timer, &QTimer::timeout, this, &Score::update);
}

void Score::start()
{
    timer->start(1000);
}

void Score::stop()
{
    timer->stop();
}

int Score::getScore()
{
    return score;
}

void Score::update()
{
    score += 10;
    qDebug() << score;
}

The full example is here完整的例子在这里

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM