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.QDateTime:获取当前日期和时间

运行

Current date and time: "2023-11-09 14:30:45"

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 方法设置定时器的时间间隔(以毫秒为单位)。例如:

cpp 复制代码
QTimer timer;
timer.setInterval(1000); // 设置定时器间隔为1秒

2. 启动和停止定时器

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

cpp 复制代码
timer.start(); // 启动定时器
// ...
timer.stop(); // 停止定时器

3. 信号和槽连接

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

cpp 复制代码
QObject::connect(&timer, &QTimer::timeout, [](){
    qDebug() << "Timer timeout";
});

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

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

cpp 复制代码
timer.setSingleShot(true); // 设置定时器为单次触发

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 来实现延时执行。以下是一个示例:

cpp 复制代码
#include <iostream>
#include <thread>
#include <chrono>

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

在上述示例中,我们使用 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 提供的 <future> 头文件中的 std::asyncstd::future 来实现异步任务的延时执行。

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

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

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

方法一:将非静态成员函数包装为静态成员函数或普通函数

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

cpp 复制代码
#include <QApplication>
#include <QTimer>
#include <QDebug>

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

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

方法二:使用 Lambda 表达式封装非静态成员函数

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

cpp 复制代码
#include <QApplication>
#include <QTimer>
#include <QDebug>

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

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

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

2.7.QElapsedTimer示例

2.7.QElapsedTimer类详解

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

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

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

  1. 检查计时器是否正在运行:
cpp 复制代码
bool isRunning = timer.isValid();

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

  1. 重置计时器:
cpp 复制代码
timer.restart();

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

  1. 静态函数:
    QElapsedTimer还提供了一些静态函数:
  • qint64 QElapsedTimer::nsecsElapsed():返回自系统启动以来的纳秒数。
  • qint64 QElapsedTimer::msecsSinceReference():返回自系统启动以来的毫秒数。
  • qint64 QElapsedTimer::msecsTo(const QElapsedTimer &other):返回从当前计时器到另一个计时器的毫秒数。
相关推荐
萝卜兽编程3 分钟前
优先级队列
c++·算法
yuwinter3 分钟前
鸿蒙HarmonyOS学习笔记(2)
笔记·学习·harmonyos
Bruce小鬼4 分钟前
QT文件基本操作
开发语言·qt
懷淰メ26 分钟前
PyQt飞机大战游戏(附下载地址)
开发语言·python·qt·游戏·pyqt·游戏开发·pyqt5
游走于计算机中摆烂的1 小时前
启动前后端分离项目笔记
java·vue.js·笔记
珹洺1 小时前
C语言数据结构——详细讲解 双链表
c语言·开发语言·网络·数据结构·c++·算法·leetcode
孙同学要努力1 小时前
C++知识整理day1——前置基础知识整理(命名空间、输入输出、函数重载、引用)
开发语言·c++
沐泽Mu2 小时前
嵌入式学习-C嘎嘎-Day05
开发语言·c++·学习
几窗花鸢2 小时前
力扣面试经典 150(下)
数据结构·c++·算法·leetcode
你可以叫我仔哥呀2 小时前
ElasticSearch学习笔记三:基础操作(一)
笔记·学习·elasticsearch