qt-C++笔记之Qt中的时间与定时器
code review!
文章目录
- qt-C++笔记之Qt中的时间与定时器
-
- 一.Qt中的日期时间数据
- 二.QTimer和QElapsedTimer
-
- 2.1.QTimer示例
- 2.2.QTimer类详解
- 2.3.QTimer::singleShot详解
- [2.4.QTimer::singleShot 可以绑定多个函数吗?](#2.4.QTimer::singleShot 可以绑定多个函数吗?)
- 2.5.C++中有类似QTimer::singleShot的方法吗?
- [2.6.将非静态成员函数作为槽函数传递给 QTimer::singleShot](#2.6.将非静态成员函数作为槽函数传递给 QTimer::singleShot)
- 2.7.QElapsedTimer示例
- 2.7.QElapsedTimer类详解
------ 杭州 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::async
和 std::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类的详细解释。
- 包含头文件:
cpp
#include <QElapsedTimer>
- 创建一个QElapsedTimer对象:
cpp
QElapsedTimer timer;
- 开始计时:
cpp
timer.start();
- 获取经过的毫秒数:
cpp
qint64 elapsedTime = timer.elapsed();
可以使用elapsed()
函数获取自计时器启动以来经过的毫秒数。如果需要获取其他时间单位,可以使用elapsed()
函数的重载版本,比如elapsedSeconds()
获取经过的秒数。
- 检查计时器是否正在运行:
cpp
bool isRunning = timer.isValid();
使用isValid()
函数可以检查计时器是否正在运行。如果计时器已经启动并且没有被重置,isValid()
返回true
;否则返回false
。
- 重置计时器:
cpp
timer.restart();
使用restart()
函数可以重置计时器,将计时器的值重置为0,并重新开始计时。
- 静态函数:
QElapsedTimer还提供了一些静态函数:
qint64 QElapsedTimer::nsecsElapsed()
:返回自系统启动以来的纳秒数。qint64 QElapsedTimer::msecsSinceReference()
:返回自系统启动以来的毫秒数。qint64 QElapsedTimer::msecsTo(const QElapsedTimer &other)
:返回从当前计时器到另一个计时器的毫秒数。