• qt-C++笔记之Qt中的时间与定时器


    qt-C++笔记之Qt中的时间与定时器

    code review!


    在这里插入图片描述

    —— 杭州 2023-11-09 夜

    一.Qt中的日期时间数据

    在这里插入图片描述

    1.1.QTime:获取当前时间

    在这里插入图片描述

    运行
    Current time: “14:30:45”

    1.2.QDate:获取当前日期

    在这里插入图片描述

    运行
    Current date: “2023-11-09”

    1.3.1.QDateTime:获取当前日期和时间

    在这里插入图片描述

    运行
    Current date and time: “2023-11-09 14:30:45”

    1.3.2.QDateTime::currentSecsSinceEpoch()函数:返回当前时间距离 Unix 纪元(1970 年 1 月 1 日 00:00:00 UTC)的秒数。

    在这里插入图片描述
    运行
    Seconds since Unix epoch: 1636661434

    1.3.3.toSecsSinceEpoch()和currentSecsSinceEpoch()

    QDateTime类有两个函数与秒数相关:toSecsSinceEpoch()currentSecsSinceEpoch()

    1. toSecsSinceEpoch()函数:

      • 函数原型:qint64 QDateTime::toSecsSinceEpoch() const
      • 描述:该函数返回当前QDateTime对象表示的时间与UNIX纪元(1970年1月1日午夜)之间的秒数差。
      • 示例代码:
        QDateTime dateTime = QDateTime::currentDateTime();
        qint64 secsSinceEpoch = dateTime.toSecsSinceEpoch();
        
        • 1
        • 2
    2. currentSecsSinceEpoch()函数:

      • 函数原型:qint64 QDateTime::currentSecsSinceEpoch()
      • 描述:该函数返回当前系统时间与UNIX纪元之间的秒数差。
      • 示例代码:
        qint64 currentSecs = QDateTime::currentSecsSinceEpoch();
        
        • 1

    这两个函数的区别在于:

    • toSecsSinceEpoch()函数是QDateTime对象的成员函数,用于获取特定时间点的秒数差。
    • currentSecsSinceEpoch()函数是QDateTime类的静态函数,用于获取当前系统时间的秒数差。

    请注意,这两个函数返回的秒数是相对于UNIX纪元的偏移量,因此它们会随着时间的推移而变化。

    1.4.QTime类详解

    在这里插入图片描述

    1.5.QDate类详解

    在这里插入图片描述

    1.6.QDateTime类详解

    在这里插入图片描述

    1.7.日期时间数据与字符串的转换

    在这里插入图片描述

    1.8.QThread::sleep()

    在这里插入图片描述

    二.QTimer和QElapsedTimer

    在这里插入图片描述

    2.1.QTimer示例

    在这里插入图片描述

    QTimer 是 Qt 框架中提供的一个定时器类,用于在特定时间间隔触发信号。它是基于事件循环机制的,可以用于执行定时操作、动画效果、周期性任务等。

    以下是关于 QTimer 的一些详解:

    1. 创建和设置定时器
    您可以使用默认构造函数创建一个 QTimer 对象,并通过 setInterval 方法设置定时器的时间间隔(以毫秒为单位)。例如:

    QTimer timer;
    timer.setInterval(1000); // 设置定时器间隔为1秒
    
    • 1
    • 2

    2. 启动和停止定时器
    使用 start 方法可以启动定时器,并开始计时。定时器开始计时后,会在指定的时间间隔内触发 timeout 信号。调用 stop 方法可以停止定时器,停止计时。例如:

    timer.start(); // 启动定时器
    // ...
    timer.stop(); // 停止定时器
    
    • 1
    • 2
    • 3

    3. 信号和槽连接
    定时器的主要作用是触发 timeout 信号,您可以通过 QObject::connect 方法将 timeout 信号连接到槽函数,以执行相应的操作。例如:

    QObject::connect(&timer, &QTimer::timeout, [](){
        qDebug() << "Timer timeout";
    });
    
    • 1
    • 2
    • 3

    在上述示例中,将定时器的 timeout 信号连接到一个 Lambda 表达式上,每次定时器计时结束时,Lambda 表达式将会执行。

    4. 单次触发和重复触发
    QTimer 默认情况下是重复触发的,即每隔指定的时间间隔,定时器就会触发一次 timeout 信号。如果您希望定时器只触发一次,可以使用 setSingleShot(true) 方法设置单次触发。例如:

    timer.setSingleShot(true); // 设置定时器为单次触发
    
    • 1

    5. 其他功能
    除了上述基本功能外,QTimer 还提供了其他一些功能和方法,例如获取剩余时间、暂停和恢复定时器等。您可以查阅 Qt 官方文档以获取更多详细信息。

    注意事项:

    • QTimer 是基于事件循环机制的,因此需要在应用程序的事件循环中才能正常工作。确保在使用 QTimer 时,应用程序的事件循环正常运行。
    • 如果在多线程环境下使用 QTimer,请注意线程安全性。

    希望这些详解对您有所帮助!如果您还有其他问题,请随时提问。

    2.2.QTimer类详解

    在这里插入图片描述

    2.3.QTimer::singleShot详解

    在这里插入图片描述

    2.4.QTimer::singleShot 可以绑定多个函数吗?

    在这里插入图片描述
    在这里插入图片描述

    2.5.C++中有类似QTimer::singleShot的方法吗?

    在 C++ 标准库中,没有直接提供类似 QTimer::singleShot 的功能。不过,您可以使用一些其他方法来实现类似的延时执行的效果。

    一种常见的方式是使用 std::this_thread::sleep_for 函数结合 std::thread 来实现延时执行。以下是一个示例:

    #include 
    #include 
    #include 
    
    void delayedFunction()
    {
        std::cout << "Delayed function executed" << std::endl;
    }
    
    int main()
    {
        std::chrono::milliseconds delay(2000); // 延时时间为2秒
    
        std::thread t([&delay]() {
            std::this_thread::sleep_for(delay);
            delayedFunction();
        });
    
        t.join(); // 等待线程执行完毕
    
        return 0;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22

    在上述示例中,我们使用 std::thread 创建了一个新的线程,在该线程中通过 std::this_thread::sleep_for 函数实现了延时。在延时结束后,执行了 delayedFunction 函数。

    请注意,延时时间通过 std::chrono::milliseconds 类型来表示,并传递给 std::this_thread::sleep_for 函数。在示例中,我们设置了延时时间为 2000 毫秒(即 2 秒)。

    这种方式可以实现类似的延时执行效果,但请注意在使用多线程时要小心处理线程间的同步和资源访问问题。

    除了上述方法,还可以使用第三方库或框架来实现类似的延时执行功能,例如 Boost 库中的 boost::asio::deadline_timer 或者使用 C++11 提供的 头文件中的 std::asyncstd::future 来实现异步任务的延时执行。

    2.6.将非静态成员函数作为槽函数传递给 QTimer::singleShot

    在 Qt 中,QTimer::singleShot 函数要求传递一个可调用的函数指针或函数对象作为定时器触发时要调用的槽函数。然而,非静态成员函数需要通过对象实例来调用,而不是直接使用函数指针。

    为了解决这个问题,您可以使用以下两种方法之一:

    方法一:将非静态成员函数包装为静态成员函数或普通函数
    您可以将非静态成员函数包装为静态成员函数或普通函数,然后将该包装函数作为参数传递给 QTimer::singleShot。在包装函数内部,通过实例化类对象,调用相应的非静态成员函数。示例如下:

    #include 
    #include 
    #include 
    
    class MyClass : public QObject
    {
        Q_OBJECT
    public slots:
        void myMemberFunction()
        {
            qDebug() << "My member function called";
        }
    };
    
    void wrapperFunction()
    {
        MyClass obj;
        obj.myMemberFunction();
    }
    
    int main(int argc, char *argv[])
    {
        QApplication app(argc, argv);
    
        QTimer::singleShot(2000, &wrapperFunction); // 2秒后执行 wrapperFunction
    
        return app.exec();
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28

    在上述示例中,我们创建了一个 MyClass 类,其中包含一个非静态成员函数 myMemberFunction。然后,我们创建了一个名为 wrapperFunction 的包装函数,在该函数内部实例化了 MyClass 对象,并调用了 myMemberFunction

    方法二:使用 Lambda 表达式封装非静态成员函数
    您可以使用 Lambda 表达式来封装非静态成员函数,并将 Lambda 表达式作为参数传递给 QTimer::singleShot。在 Lambda 表达式内部,通过对象实例调用相应的非静态成员函数。示例如下:

    #include 
    #include 
    #include 
    
    class MyClass : public QObject
    {
        Q_OBJECT
    public slots:
        void myMemberFunction()
        {
            qDebug() << "My member function called";
        }
    };
    
    int main(int argc, char *argv[])
    {
        QApplication app(argc, argv);
    
        MyClass obj;
        QTimer::singleShot(2000, [&obj]() { obj.myMemberFunction(); }); // 2秒后执行 Lambda 表达式
    
        return app.exec();
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23

    在上述示例中,我们创建了一个 MyClass 类和一个 MyClass 对象 obj。然后,我们使用 Lambda 表达式 [&obj]() 来封装非静态成员函数,并在 Lambda 表达式中通过对象实例 obj 调用 myMemberFunction

    这两种方法都可以解决将非静态成员函数作为槽函数传递给 QTimer::singleShot 的问题。

    2.7.QElapsedTimer示例

    在这里插入图片描述

    2.7.QElapsedTimer类详解

    在这里插入图片描述

    QElapsedTimer类是Qt框架中的一个工具类,用于测量时间间隔。它提供了一个高分辨率的计时器,可以用来测量代码执行时间、性能分析等。下面是对QElapsedTimer类的详细解释。

    1. 包含头文件:
    #include 
    
    • 1
    1. 创建一个QElapsedTimer对象:
    QElapsedTimer timer;
    
    • 1
    1. 开始计时:
    timer.start();
    
    • 1
    1. 获取经过的毫秒数:
    qint64 elapsedTime = timer.elapsed();
    
    • 1

    可以使用elapsed()函数获取自计时器启动以来经过的毫秒数。如果需要获取其他时间单位,可以使用elapsed()函数的重载版本,比如elapsedSeconds()获取经过的秒数。

    1. 检查计时器是否正在运行:
    bool isRunning = timer.isValid();
    
    • 1

    使用isValid()函数可以检查计时器是否正在运行。如果计时器已经启动并且没有被重置,isValid()返回true;否则返回false

    1. 重置计时器:
    timer.restart();
    
    • 1

    使用restart()函数可以重置计时器,将计时器的值重置为0,并重新开始计时。

    1. 静态函数:
      QElapsedTimer还提供了一些静态函数:
    • qint64 QElapsedTimer::nsecsElapsed():返回自系统启动以来的纳秒数。
    • qint64 QElapsedTimer::msecsSinceReference():返回自系统启动以来的毫秒数。
    • qint64 QElapsedTimer::msecsTo(const QElapsedTimer &other):返回从当前计时器到另一个计时器的毫秒数。

    在这里插入图片描述

  • 相关阅读:
    智慧社区搭载联网智能门锁,出行体验不一般!
    柔顺机构学读书笔记1:悬臂梁变形
    stm32 Keil V5 开发pack突然丢失
    深度剖析集成学习Xgboost
    C++之多态二三事
    11.模型选择,欠拟合和过拟合
    10.(Python数模)(预测模型二)LSTM回归网络(1→1)
    这8款浏览器兼容性测试工具,用了以后测试效率可以“起飞”~~
    python实现 合并相同编号的证书名称
    Java IO流 要点
  • 原文地址:https://blog.csdn.net/weixin_43297891/article/details/134323533