【Qt 延迟手段】Qt中实现延迟和休眠的多种方法


第一章:Qt中实现延迟和休眠的基础方法

1.1 QThread的使用

QThread 是Qt中用于多线程编程的基础类。在这个类中,有一个非常有用的方法叫做 msleep,它可以用于在当前线程中实现延迟。

代码示例

#include <QThread>

void delayFunction() {
    
    
    QThread::msleep(1000);  // 延迟1000毫秒,即1秒
}

这里的 QThread::msleep(1000); 将会使当前线程暂停1秒。这是一个阻塞性的延迟,意味着它会阻塞当前线程的执行。

1.2 QTimer的使用

QTimer 是另一个用于实现延迟和定时任务的类。与 QThread 不同,QTimer 是非阻塞性的。

代码示例

#include <QTimer>
#include <QObject>

class MyClass : public QObject {
    
    
    Q_OBJECT
public slots:
    void mySlot() {
    
    
        // 执行延迟后的操作
    }
};

// 在某个函数中
MyClass obj;
QTimer::singleShot(1000, &obj, SLOT(mySlot()));  // 1秒后执行mySlot

这里,QTimer::singleShot 方法会在1秒后触发 mySlot 方法,而不会阻塞当前线程。

1.3 QElapsedTimer的使用

QElapsedTimer 是用于测量经过的时间的类。它通常用于性能分析。

代码示例

#include <QElapsedTimer>

QElapsedTimer timer;
timer.start();

// 执行某些操作

qint64 elapsed = timer.elapsed();  // 获取经过的时间(毫秒)

1.4 QDateTime的使用

QDateTime 类提供了日期和时间的功能,也可以用于实现延迟。

代码示例

#include <QDateTime>
#include <QCoreApplication>

void delay(int msec) {
    
    
    QDateTime dieTime = QDateTime::currentDateTime().addMSecs(msec);
    while (QDateTime::currentDateTime() < dieTime) {
    
    
        QCoreApplication::processEvents(QEventLoop::AllEvents, 100);
    }
}

这里,我们使用 QDateTime::currentDateTime().addMSecs(msec) 来获取延迟后的时间,然后用一个循环来等待。

正如Bjarne Stroustrup在《The C++ Programming Language》中所说:“C++ 是一种多范式编程语言,支持不同的编程风格。”[1] 在Qt中,这些不同的延迟和休眠方法就是多范式编程思想的体现。

第二章:Qt5与Qt6之间的差异

2.1 QThread的差异

在Qt5和Qt6中,QThread 的基础功能大致相同。但是,Qt6引入了一些新的API和改进,使得多线程编程更加方便。

扫描二维码关注公众号,回复: 16693767 查看本文章

代码示例

Qt5中的QThread使用:

QThread thread;
Worker worker;

worker.moveToThread(&thread);
connect(&thread, SIGNAL(started()), &worker, SLOT(doWork()));
thread.start();

Qt6中的QThread使用:

QThread thread;
Worker worker;

worker.moveToThread(&thread);
connect(&thread, &QThread::started, &worker, &Worker::doWork);  // 使用新的信号和槽语法
thread.start();

在Qt6中,信号和槽的连接方式有所改进,使得代码更加清晰。

2.2 QTimer的差异

QTimer 在Qt6中进行了一些微小的改进,但基本用法保持不变。

代码示例

Qt5和Qt6中的QTimer使用基本相同:

QTimer timer;
connect(&timer, SIGNAL(timeout()), this, SLOT(update()));
timer.start(1000);

2.3 QElapsedTimer和QDateTime的差异

这两个类在Qt5和Qt6中没有显著的差异。它们都用于时间测量和延迟,API也基本保持一致。

2.4 总结

Qt6相对于Qt5进行了一些改进和优化,但大多数用于延迟和休眠的类和方法都保持不变。这意味着从Qt5迁移到Qt6通常是平滑的,不需要大量的代码更改。

正如一位名人曾说:“时间是一切财富中最宝贵的财富。”[2] 在软件开发中,对时间的精确控制是至关重要的,Qt通过提供多种方法来实现这一点。

第三章:Linux下的底层实现

3.1 QThread在Linux下的底层实现

在Linux系统中,QThread 的底层实现基于POSIX线程(也称为Pthreads)。QThread::msleep() 方法实际上是一个对 nanosleepusleep 系统调用的封装。

底层源码

在某些Linux发行版中,这一功能在 qthread_unix.cpp 文件中的 QThread::msleep 函数里实现。

void QThread::msleep(unsigned long msecs)
{
    
    
    struct timespec ts = {
    
     msecs / 1000, (msecs % 1000) * 1000 * 1000 };
    nanosleep(&ts, NULL);
}

3.2 QTimer在Linux下的底层实现

QTimer 在Linux下通常使用时间戳或者Linux的定时器机制(例如 timerfd)进行实现。

底层源码

在Linux系统中,QTimer 的实现通常位于 qtimer_linux.cpp 文件中。

// 示例代码,展示timerfd的使用
int timerFd = timerfd_create(CLOCK_MONOTONIC, TFD_NONBLOCK);

3.3 QElapsedTimer和QDateTime在Linux下的底层实现

QElapsedTimer 在Linux下通常使用 clock_gettime 函数。而 QDateTime 则通常使用 gettimeofdaytime 函数。

底层源码

在Linux系统中,这些功能的实现通常位于 qelapsedtimer_unix.cppqdatetime_unix.cpp 文件中。

// QElapsedTimer 使用 clock_gettime
struct timespec ts;
clock_gettime(CLOCK_MONOTONIC, &ts);

// QDateTime 使用 gettimeofday
struct timeval tv;
gettimeofday(&tv, NULL);

第四章:方法对比与使用建议

4.1 QThread vs QTimer vs QElapsedTimer vs QDateTime

这几种方法各有优缺点,选择哪一种取决于具体的应用场景。

  • QThread:适用于需要长时间运行或需要并行处理的任务。
  • QTimer:适用于需要定时触发某个事件或函数的场景。
  • QElapsedTimer:适用于需要精确测量时间间隔的场景。
  • QDateTime:适用于需要处理日期和时间的场景。

4.2 何时使用哪种方法

  • 需要并行处理任务:使用QThread。
  • 需要定时触发事件:使用QTimer。
  • 需要精确测量时间:使用QElapsedTimer。
  • 需要处理日期和时间:使用QDateTime。

4.3 在不同版本和操作系统下的注意事项

  • 在Qt5和Qt6之间迁移时,注意API的微小变化。
  • 在Linux系统下,了解底层实现可以帮助你更有效地使用这些方法。

4.4 总结与建议

选择合适的方法不仅可以提高代码的效率,还可以使代码更易于维护。正如一位名人曾说:“选择是一种能力,也是一种责任。”[4]

在编程中,合理地选择延迟和休眠的方法,就像在生活中做出明智的选择一样,都是至关重要的。

结语

在我们的编程学习之旅中,理解是我们迈向更高层次的重要一步。然而,掌握新技能、新理念,始终需要时间和坚持。从心理学的角度看,学习往往伴随着不断的试错和调整,这就像是我们的大脑在逐渐优化其解决问题的“算法”。

这就是为什么当我们遇到错误,我们应该将其视为学习和进步的机会,而不仅仅是困扰。通过理解和解决这些问题,我们不仅可以修复当前的代码,更可以提升我们的编程能力,防止在未来的项目中犯相同的错误。

我鼓励大家积极参与进来,不断提升自己的编程技术。无论你是初学者还是有经验的开发者,我希望我的博客能对你的学习之路有所帮助。如果你觉得这篇文章有用,不妨点击收藏,或者留下你的评论分享你的见解和经验,也欢迎你对我博客的内容提出建议和问题。每一次的点赞、评论、分享和关注都是对我的最大支持,也是对我持续分享和创作的动力。


阅读我的CSDN主页,解锁更多精彩内容:泡沫的CSDN主页
在这里插入图片描述

猜你喜欢

转载自blog.csdn.net/qq_21438461/article/details/132916934
QT